namespace std {
template <class... Traits>
struct conjunction;
template <class... Traits>
inline constexpr bool conjunction_v = conjunction<Traits...>::value;
}
概要
複数の特性(bool値を返すメタ関数)の論理積を計算する。
要件
Traits内の型のうち、Bi::valueが実体化されるものは、基底クラスとして使用可能で(final指定されていない)、boolに変換可能なメンバ変数valueを持つこと。- 短絡評価によって
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までは定義されているが有効化されていない。
参照
- C++17 で追加された std::conjunction/std::disjunction メタ関数 - Secret Garden(Instrumental)
- conjunction/disjunctionと短絡インスタンス化 - yohhoyの日記
- Logical Operator Type Traits (revision 1)
- LWG Issue 2557. Logical operator traits are broken in the zero-argument case
- C++17の策定中に、引数が0個の場合(
conjunction<>はtrue_type、disjunction<>はfalse_type)を正しく扱うよう文言が整理された
- C++17の策定中に、引数が0個の場合(
- LWG Issue 2567. Specification of logical operator traits uses
BaseCharacteristic, which is defined only forUnaryTypeTraitsandBinaryTypeTraits- C++17の策定中に、
conjunction/disjunction/negationのBaseCharacteristic(派生元の基底)の規定が、どの型から派生するかを明示する形に整理された
- C++17の策定中に、
- LWG Issue 2569.
conjunctionanddisjunctionrequirements are too strict- C++17の策定中に、テンプレート引数のうち
Bi::valueが実体化されるものだけが基底クラスとして使用可能であればよい、と要件が緩和された(短絡評価される型には要件が及ばない)
- C++17の策定中に、テンプレート引数のうち