C++17 で追加された std::conjunction/std::disjunction メタ関数
知らなかったので覚書。
C++17 で std::conjunction
と std::disjunction
という2つのメタ関数が追加されました。
この2つのメタ関数はいずれも可変長テンプレート引数を受け取ります。
具体的にどのようなメタ関数なのかは以下のコードを見てください。
#include <type_traits> int main(){ using true_ = std::true_type; using false_ = std::false_type; // 引数型の ::value が全て true なら true static_assert( std::conjunction<true_, true_, true_>{}, ""); static_assert(!std::conjunction<true_, false_, true_>{}, ""); // 引数型の ::value のいずれかが true なら true static_assert( std::disjunction<true_, false_, false_>{}, ""); static_assert(!std::disjunction<false_, false_, false_>{}, ""); return 0; }
std::conjunction
は全ての型で &&
し、std::disjunction
は全ての型で ||
するって感じですね。
どういう時に役立つの
例えば、『任意の複数の型が同じ型かどうか』を判定するメタ関数を定義するとします。
そういう場合は、std::conjunction
を使えば簡単に処理する事が出来ます。
// 再帰みたいなことをしないでも実装できた!! template<typename T, typename... Args> struct all_of : std::conjunction<std::is_same<T, Args>...>{}; static_assert( all_of<int, int, int>{}, ""); static_assert(!all_of<int, int, float>{}, ""); static_assert(!all_of<int, int, int&>{}, "");
これは便利だなあ…。
ちなみに C++17 では fold expression を使って次のように実装することも出来たりします。
// std::conjunction すらいらない!! template<typename T, typename... Args> struct all_of : std::bool_constant<(... && std::is_same_v<T, Args>)>{}; static_assert( all_of<int, int, int>{}, ""); static_assert(!all_of<int, int, float>{}, ""); static_assert(!all_of<int, int, int&>{}, "");
C++14 で追加されればよかったのに…。