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