C++20:使用概念实现 std::is_constructible

Man*_*mon 1 c++ type-traits c++-concepts c++20

是否有一种可移植的方法来std::is_constructible使用概念来实现而无需仅STL使用requires表达式或模板元编程?

考虑这段代码:

template <class T, class... Args>
struct is_constructible
    : std::bool_constant<requires {
      new T(std::declval<Args>()...);
    }> {
};
Run Code Online (Sandbox Code Playgroud)

它适用于除引用之外的其他数据类型,因为不能使用new引用类型。

// Test cases
auto main() -> int {
  static_assert(is_constructible<int>::value);
  static_assert(is_constructible<int, int>::value);
  static_assert(is_constructible<int, float>::value);
  static_assert(!is_constructible<int, int *>::value);
  static_assert(is_constructible<int &, int &>::value);
  static_assert(is_constructible<int &&, int &&>::value);
  static_assert(!is_constructible<void, void>::value);
  static_assert(!is_constructible<int(), int()>::value);
  static_assert(is_constructible<int (*)(), int()>::value);
  static_assert(!is_constructible<intptr_t, int *>::value);
  static_assert(!is_constructible<int &, float &>::value);

  static_assert(std::is_constructible<int>::value);
  static_assert(std::is_constructible<int, int>::value);
  static_assert(std::is_constructible<int, float>::value);
  static_assert(!std::is_constructible<int, int *>::value);
  static_assert(std::is_constructible<int &, int &>::value);
  static_assert(std::is_constructible<int &&, int &&>::value);
  static_assert(!std::is_constructible<void, void>::value);
  static_assert(!std::is_constructible<int(), int()>::value);
  static_assert(std::is_constructible<int (*)(), int()>::value);
  static_assert(!std::is_constructible<intptr_t, int *>::value);
  static_assert(!std::is_constructible<int &, float &>::value);
  
  return {};
}
Run Code Online (Sandbox Code Playgroud)

T.C*_*.C. 7

不,当然不是“干净利落”。

事实上,标准化过程中的早期提案试图constructible_from使用requires表达式来实现,但是有太多的极端情况,我们放弃了并用类型特征来指定它。