C++17 から std::bool_constant というメタ関数にありがちな型をテンプレにしたものが導入されました。
これをメタ関数で使うと理解が深まりそうなので、特に深く考えずにメタ関数の機能のチェックとして使ってみましょうかね。
マクロについては クロスコンパイルのための組み込みマクロ を参照くださいね。
main.cpp.
1 #if __cplusplus != 201703L 2 # pragma message "-std=c++17を指定してください" 3 #endif 4 5 #if defined(__GNUC__) && (__GNUC__ < 7) 6 # ifndef __clang__ 7 # pragma message "gccのバージョンが古いです" 8 # endif 9 #elif defined(__clang__) && (__clang_major__ < 6) 10 # pragma message "clangのバージョンが古いです" 11 #endif 12 13 #include <type_traits> 14 15 template<typename... T> 16 struct is_same : std::false_type {}; 17 18 template<typename T> 19 struct is_same<T,T> : std::true_type {}; 20 21 static_assert( 22 is_same<std::bool_constant<true>, 23 typename std::disjunction<std::bool_constant<true>>::type>::value 24 ); 25 26 static_assert( 27 is_same<std::bool_constant<false>, 28 typename std::disjunction<std::bool_constant<false>>::type>::value 29 ); 30 31 int main(){}
まずひとつ目のテンプレートテクニックです。
15 template<typename... T> 16 struct is_same : std::false_type {}; 17 18 template<typename T> 19 struct is_same<T,T> : std::true_type {};
この is_same は std::is_same と同じような機能を持ちます。
基本的には 2 つの T の型が同じなら std::true_type を継承し、それ以外は std::false_type を継承します。
もうひとつのテクニックは std::bool_constant です。
これは単に true か false の値をもつためのラップ型なので std::disjunction の引数に指定が可能です。
21 static_assert( 22 is_same<std::bool_constant<true>, 23 typename std::disjunction<std::bool_constant<true>>::type>::value 24 ); 25 26 static_assert( 27 is_same<std::bool_constant<false>, 28 typename std::disjunction<std::bool_constant<false>>::type>::value 29 );
この場面では std::bool_constant<true> と std::disjunction<std::bool_constant<false>>::type が同じという結果になってます。
Copyright 2017-2018, by Masaki Komatsu