Edited at

メモ:std::conditionalでif~else if~elseみたいなことをしようとすると見づらい

More than 1 year has passed since last update.

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
>;

式が短くなったりはしないが、分かりやすくはなっている気がします。