Namespaces
Variants

std::experimental:: conjunction

From cppreference.net
ヘッダーで定義 <experimental/type_traits>
template < class ... B >
struct conjunction ;
(ライブラリ基盤 TS v2)

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

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

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

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

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

目次

テンプレートパラメータ

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

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

template < class ... B >
constexpr bool conjunction_v = conjunction < B... > :: value ;
(ライブラリファンダメンタルTS v2)

実装例

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に変換された ::value がfalseとなる最初のBから継承するか、すべてがtrueに変換される場合は最後のBから継承します。例えば、 conjunction < std:: integral_constant < int , 2 > , std:: integral_constant < int , 4 >> :: value 4 です。

#include <experimental/type_traits>
#include <iostream>
// funcは全てのTs...が同じ型を持つ場合に有効化される
template<typename T, typename... Ts>
constexpr std::enable_if_t<std::experimental::conjunction_v<std::is_same<T, Ts>...>>
func(T, Ts...)
{
    std::cout << "All types are the same.\n";
}
template<typename T, typename... Ts>
constexpr std::enable_if_t<!std::experimental::conjunction_v<std::is_same<T, Ts>...>>
func(T, Ts...)
{
    std::cout << "Types differ.\n";
}
int main()
{
    func(1, 2'7, 3'1);    
    func(1, 2.7, '3');    
}

出力:

All types are the same.
Types differ.

関連項目

可変引数論理積メタ関数
(クラステンプレート)