名前空間
変種
操作

std::conjunction

From cppreference.com
< cpp‎ | types
 
 
メタプログラミングライブラリ
型特性
型のカテゴリ
(C++11)
(C++11)(DR*)
(C++11)
(C++11)
(C++11)
(C++11)
(C++11)
(C++11) 
(C++11)
(C++11)
型のプロパティ
(C++11)
(C++11)
(C++14)
(C++11)(C++26で非推奨)
(C++11)(C++20まで*)
(C++11)(C++20で非推奨)
(C++11)
型特性定数
メタ関数
conjunction
(C++17)
(C++17)
サポートされている操作
関係とプロパティクエリ
型の変更
(C++11)(C++11)(C++11)
型の変換
(C++11)(C++23で非推奨)
(C++11)(C++23で非推奨)
(C++11)
(C++11)(C++20まで*)(C++17)

(C++11)
(C++17)
コンパイル時有理数演算
コンパイル時整数シーケンス
 
ヘッダ <type_traits> で定義
template< class... B >
struct conjunction;
(C++17以降)

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

特殊化 std::conjunction<B1, ..., BN> は、以下のいずれかである公開かつ曖昧さのない基底を持ちます。

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

基底クラスのメンバー名(conjunction および operator= を除く)は隠蔽されず、conjunction で曖昧さなく利用できます。

conjunction はショートサーキット評価されます。もし bool(Bi::value) == false となるテンプレート型引数 Bi が存在する場合、conjunction<B1, ..., BN>::value のインスタンス化は j > iBj::value のインスタンス化を必要としません。

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

目次

[編集] テンプレートパラメータ

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

[編集] ヘルパー変数テンプレート

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 から継承するわけではありません。それは、bool に明示的に変換された ::valuefalse となる最初の B から継承するか、すべてが true に変換される場合は最後の B から継承するだけです。例えば、std::conjunction<std::integral_constant<int, 2>, std::integral_constant<int, 4>>::value4 です。

ショートサーキットによるインスタンス化は、conjunction畳み込み式と区別します。(... && Bs::value) のような畳み込み式は Bs のすべての B をインスタンス化しますが、std::conjunction_v<Bs...> は値が決定できるとすぐにインスタンス化を停止します。これは、後の型がインスタンス化にコストがかかる場合や、間違った型でインスタンス化された場合にハードエラーを引き起こす可能性がある場合に特に役立ちます。

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

[編集]

#include <iostream>
#include <type_traits>
 
// func is enabled if all Ts... have the same type as 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";
}
 
// otherwise
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メタ関数
(クラステンプレート) [編集]
English 日本語 中文(简体) 中文(繁體)