yohhoyの日記

技術的メモをしていきたい日記

条件付きexplicit指定子

C++2a(C++20)言語仕様では 条件付きexplicit指定子 が追加され、pairtupleなどの型Tを値保持するクラステンプレートにおいて、型Tコンストラクタ実装時のexplicit性継承(→id:yohhoy:20150416)が容易になる。

// C++17仕様
template <typename T1, typename T2>
struct pair {
  // non-explicitコンストラクタ
  template <typename U1=T1, typename U2=T2,
    std::enable_if_t<
      std::is_constructible_v<T1, U1> &&
      std::is_constructible_v<T2, U2> &&
      std::is_convertible_v<U1, T1> &&
      std::is_convertible_v<U2, T2>
    , int> = 0>
  constexpr pair(U1&&, U2&&);
  
  // explicitコンストラクタ
  template <typename U1=T1, typename U2=T2,
    std::enable_if_t<
      std::is_constructible_v<T1, U1> &&
      std::is_constructible_v<T2, U2> &&
      !(std::is_convertible_v<U1, T1> &&
        std::is_convertible_v<U2, T2>)
     , int> = 0>
  explicit constexpr pair(U1&&, U2&&);
};
// C++2a仕様: Concept+explicit(bool)
template <typename T1, typename T2>
struct pair {
  // explicit指定有無はT1, T2, U1, U2型に依存
  template <typename U1=T1, typename U2=T2>
    requires std::is_constructible_v<T1, U1> &&
             std::is_constructible_v<T2, U2>
  explicit(!std::is_convertible_v<U1, T1> ||
           !std::is_convertible_v<U2, T2>)
  constexpr pair(U1&&, U2&&);
};

関連URL