• Class / Function / Type

      std::
    • Header file

      <>
    • Other / All

    最終更新日時(UTC):
    が更新

    履歴 編集

    class template
    <type_traits>

    std::disjunction

    namespace std {
      template <class... Traits>
      struct disjunction;
    
      template <class... Traits>
      inline constexpr bool disjunction_v = disjunction<Traits...>::value;
    }
    

    概要

    複数の特性(bool値を返すメタ関数)の論理和を計算する。

    要件

    Traits内の全ての型は基底クラスとして使用可能で(final指定されていない)、boolに変換可能なメンバ変数valueを持つこと。

    効果

    sizeof...(Traits) == 0ならばfalse_typeから派生し

    sizeof...(Traits) == 1ならばそのTraitsから派生し

    sizeof...(Traits) > 1ならばTraits::value == trueとなる最初の型か、Traits列の一番最後の型から派生する。

    すなわち、(結果だけを見れば)全てのTraits::valueを||演算子で結合した結果に等しい((... || Traits::value))。

    備考

    disjunctionは短絡評価される。

    ||演算子を用いると||で連結されているすべてのメタ関数のインスタンス化が行われるのに対して、disjunctionでは::value==trueとなるメタ関数が出現した時点で処理は終了し、後続のメタ関数のインスタンス化は行われない。

    #include <type_traits>
    #include <iostream>
    
    template<typename T>
    using is_some_of_pointer = std::disjunction<std::is_pointer<T>, std::is_member_object_pointer<T>, std::is_member_function_pointer<T>>;
    
    template<typename T, std::enable_if_t<is_some_of_pointer<T>::value, std::nullptr_t> = nullptr>
    void f(T) {
      std::cout << "Tは何らかのポインタ" << std::endl;
    }
    
    template<typename T, std::enable_if_t<!is_some_of_pointer<T>::value, std::nullptr_t> = nullptr>
    void f(T) {
      std::cout << "Tはポインタではない" << std::endl;
    }
    
    struct s {
      void member_function(){};
      int member_object;
    };
    
    int main()
    {
      int n = 1234;
      int* p = &n;
    
      f(p);
      f(n);
      f(&s::member_object);
      f(&s::member_function);
    }
    

    出力

    Tは何らかのポインタ
    Tはポインタではない
    Tは何らかのポインタ
    Tは何らかのポインタ
    

    バージョン

    言語

    • C++17

    処理系

    • Clang: 3.8
    • GCC: 6.3
    • Visual C++: 2015 update2 , 2017
      • disjunction_vは、2015 update3までは定義されているが有効化されていない。

    参照