namespace std {
template <class... Traits>
struct disjunction;
template <class... Traits>
inline constexpr bool disjunction_v = disjunction<Traits...>::value;
}
概要
複数の特性(bool値を返すメタ関数)の論理和を計算する。
要件
Traits内の全ての型は基底クラスとして使用可能で(final指定されていない)、boolに変換可能なメンバ変数valueを持つこと。
効果
sizeof...(Traits) == 0
ならばfalse_type
から派生し
sizeof...(Traits) == 1
ならばそのTraitsから派生し
sizeof...(Traits) > 1
ならばTraits::value == true
となる最初の型か、Traits列の一番最後の型から派生する。
すなわち、(結果だけを見れば)全てのTraits::valueを||演算子で結合した結果に等しい((... || Traits::value)
)。
備考
disjunction
は短絡評価される。
||演算子を用いると||で連結されているすべてのメタ関数のインスタンス化が行われるのに対して、disjunction
では::value==trueとなるメタ関数が出現した時点で処理は終了し、後続のメタ関数のインスタンス化は行われない。
例
#include <type_traits>
#include <iostream>
template<typename T>
using is_some_of_pointer = std::disjunction<std::is_pointer<T>, std::is_member_object_pointer<T>, std::is_member_function_pointer<T>>;
template<typename T, std::enable_if_t<is_some_of_pointer<T>::value, std::nullptr_t> = nullptr>
void f(T) {
std::cout << "Tは何らかのポインタ" << std::endl;
}
template<typename T, std::enable_if_t<!is_some_of_pointer<T>::value, std::nullptr_t> = nullptr>
void f(T) {
std::cout << "Tはポインタではない" << std::endl;
}
struct s {
void member_function(){};
int member_object;
};
int main()
{
int n = 1234;
int* p = &n;
f(p);
f(n);
f(&s::member_object);
f(&s::member_function);
}
出力
Tは何らかのポインタ
Tはポインタではない
Tは何らかのポインタ
Tは何らかのポインタ
バージョン
言語
- C++17
処理系
- Clang: 3.8 ✅
- GCC: 6.3 ✅
- Visual C++: 2015 update2 ✅, 2017 ✅
disjunction_v
は、2015 update3までは定義されているが有効化されていない。