C++14 で static_if 書いてみた
上げるの忘れてた。 generic lambda を使っていい感じに static_if を書いてみました。
ソース
#include <iostream> template<typename Then, typename Else> auto static_if(std::integral_constant<bool, true>, Then then, Else else_){ return then; } template<typename Then, typename Else> auto static_if(std::integral_constant<bool, false>, Then then, Else else_){ return else_; } template<bool Cond, typename Then, typename Else> auto static_if(Then then, Else else_){ return static_if(std::integral_constant<bool, Cond>{}, then, else_); } template<bool Cond, typename Then> auto static_if(Then then){ return static_if<Cond>(then, [](...){}); } #include <boost/type_traits/has_plus.hpp> template<typename T> auto twice(T t){ static_if<boost::has_plus<T, T>::value>( [](auto t){ std::cout << t + t << std::endl; }, [](...){ std::cout << "Error" << std::endl; } )(t); } template<int N> int test(){ return static_if<(N > 0)>( [](auto n){ return N + test<decltype(n){}-1>(); }, [](...){ return N; } )(std::integral_constant<int, N>{}); } int main(){ twice(10); twice(std::string("homu")); twice("homu"); std::cout << test<5>() << std::endl; return 0; }
出力結果
20 homuhomu Error 15
then 節のコードを generic lambda で書き、参照した値を generic lambda 経由で使用することで偽の場合でもコンパイルエラーにならないようにしています。 ただ、型を使用したい場合は引数値として渡してやる必要があるのでちょっと手間ではあります。 それでもだいぶすっきりと書けるのではないかな。