std::conditional
をがしがし書いてると、なんだか冗長だしどうやって整形したらいいのか分からないです。
c++
template<bool condition, typename IfTrue, typename IfFalse>
using conditional_t = typename std::conditional<condition, IfTrue, IfFalse>::type;
template<typename T>
using bar =
conditional_t<cond1, type1,
conditional_t<cond2, type2,
conditional_t<cond3, type3,
default_type>>>;
ネストがよく分かりません。
c++
template<typename T>
using bar =
conditional_t<cond1,
type1,
conditional_t<cond2,
type2,
conditional_t<cond3,
type3,
default_type
>
>
>;
if文っぽく整形してみてもダサい。
c++
template<typename T>
using bar =
conditional_t<cond1, type1,
conditional_t<cond2, type2,
conditional_t<cond3, type3,
default_type>>>;
むしろこの方がマシなような気もしますが、最後の連続する山括弧はどうにかならないものでしょうか。
という訳で、こんな解決策はどうでしょう。
c++
template<typename ...Args>
struct first_enabled {};
template<typename T, typename ...Args>
struct first_enabled<std::enable_if<true, T>, Args...> { using type = T; };
template<typename T, typename ...Args>
struct first_enabled<std::enable_if<false, T>, Args...>: first_enabled<Args...> {};
template<typename T, typename ...Args>
struct first_enabled<T, Args...> { using type = T; };
template<typename ...Args>
using first_enabled_t = typename first_enabled<Args...>::type;
std::enable_if<T>
を並べて、最初に条件が真になった型になるテンプレートエイリアス。
std::enable_if<T>
以外の型が渡されると常に条件が真とみなしてその型になるので、最後にデフォルトを追加することも可能。
上の例をこれをつかって書き直すと、こうなる。
c++
template<typename T>
using bar = first_enabled_t<
std::enable_if<cond1, type1>,
std::enable_if<cond2, type2>,
std::enable_if<cond3, type3>,
default_type
>;
式が短くなったりはしないが、分かりやすくはなっている気がします。