Namespaces
Variants

std:: conjunction

From cppreference.net
Metaprogramming library
Type traits
Type categories
(C++11)
(C++11) ( DR* )
Type properties
(C++11)
(C++11)
(C++14)
(C++11) (deprecated in C++26)
(C++11) ( until C++20* )
(C++11) (deprecated in C++20)
(C++11)
Type trait constants
Metafunctions
conjunction
(C++17)
(C++17)
Supported operations
Relationships and property queries
Type modifications
Type transformations
(C++11) (deprecated in C++23)
(C++11) (deprecated in C++23)
(C++11)
(C++11) ( until C++20* ) (C++17)

Compile-time rational arithmetic
Compile-time integer sequences
定義先ヘッダ <type_traits>
template < class ... B >
struct conjunction ;
(C++17以降)

型特性 B... 論理積 を形成し、特性シーケンスに対して論理AND演算を実行します。

特殊化 std :: conjunction < B1, ..., BN > は、公開かつ明確な基底クラスを持ち、それは

  • sizeof... sizeof... ( B ) == 0 の場合、 std:: true_type ; それ以外の場合
  • B1, ..., BN 内の最初の型 Bi bool ( Bi :: value ) == false となるもの、またはそのような型が存在しない場合は BN

基底クラスのメンバ名は、 conjunction および operator= を除いて、隠蔽されずに conjunction 内で曖昧性なく利用可能です。

conjunctionは短絡評価を行います:もし Bi のようなテンプレート型引数が存在し、 bool ( Bi :: value ) == false である場合、 conjunction < B1, ..., BN > :: value のインスタンス化は j > i となる Bj :: value のインスタンス化を必要としません。

プログラムが std::conjunction または std::conjunction_v に対する特殊化を追加する場合、動作は未定義です。

目次

テンプレートパラメータ

B... - インスタンス化されるすべてのテンプレート引数 Bi は、基底クラスとして使用可能であり、 Bi :: value メンバーを定義し、それが bool に変換可能でなければならない

ヘルパー変数テンプレート

template < class ... B >
constexpr bool conjunction_v = conjunction < B... > :: value ;
(C++17以降)

実装例

template<class...>
struct conjunction : std::true_type {};
template<class B1>
struct conjunction<B1> : B1 {};
template<class B1, class... Bn>
struct conjunction<B1, Bn...>
    : std::conditional_t<bool(B1::value), conjunction<Bn...>, B1> {};

注記

conjunction の特殊化は必ずしも std:: true_type または std:: false_type から継承するわけではありません。これは単に、 ::value bool に明示的に変換された際に false となる最初の B から継承するか、すべての B true に変換される場合は最後の B から継承します。例えば、 std :: conjunction < std:: integral_constant < int , 2 > , std:: integral_constant < int , 4 >> :: value 4 です。

短絡評価のインスタンス化は、 conjunction fold expressions と区別します:fold expression、例えば ( ... && Bs :: value ) は、 Bs 内のすべての B をインスタンス化しますが、 std :: conjunction_v < Bs... > は値が決定可能になるとインスタンス化を停止します。これは、後の型のインスタンス化が高コストである場合や、誤った型でインスタンス化された際にハードエラーを引き起こす可能性がある場合に特に有用です。

機能テスト マクロ 標準 機能
__cpp_lib_logical_traits 201510L (C++17) 論理演算子型特性

#include <iostream>
#include <type_traits>
// funcは全てのTs...がTと同じ型の場合に有効化される
template<typename T, typename... Ts>
std::enable_if_t<std::conjunction_v<std::is_same<T, Ts>...>>
func(T, Ts...)
{
    std::cout << "All types in pack are the same.\n";
}
// それ以外の場合
template<typename T, typename... Ts>
std::enable_if_t<!std::conjunction_v<std::is_same<T, Ts>...>>
func(T, Ts...)
{
    std::cout << "Not all types in pack are the same.\n";
}
template<typename T, typename... Ts>
constexpr bool all_types_are_same = std::conjunction_v<std::is_same<T, Ts>...>;
static_assert(all_types_are_same<int, int, int>);
static_assert(not all_types_are_same<int, int&, int>);
int main()
{
    func(1, 2, 3);
    func(1, 2, "hello!");
}

出力:

All types in pack are the same.
Not all types in pack are the same.

関連項目

(C++17)
論理NOTメタ関数
(クラステンプレート)
可変長論理ORメタ関数
(クラステンプレート)