概念:需要一个类型的函数而不默认构造该类型

Concepts: require a function on a type without default constructing that type

我需要要求某个类型 A 存在一个函数 f(A, A::B).

我正在通过使用 A 和 A::B 的实例调用 f 来测试它。是否有一种不那么夸张的方法来测试依赖类型的实例而不需要默认可构造的?

template <class Container>
concept CanPutData = requires (Container a)
{
  //put(typename Container::data_type{}, a);  // overconstrained
  put(*reinterpret_cast<typename Container::data_type*>(0), a); // oof
};

void test(CanPutData auto container) {}

template<class Container>
void put(typename Container::data_type const& data, Container& into) {}


template<class Data>
struct data_container { using data_type = Data; };
struct not_default_constructible_data { int& v; };

int main()
{
  test(data_container<not_default_constructible_data>{});

  return 0;
}

同样的方法你已经得到了一个 Container 而不需要它是默认可构造的:只需将它粘贴在 requires 表达式的参数列表中:

template <class Container>
concept CanPutData = requires (Container container, typename Container::data_type data)
{
  put(data, container);
};

你也可以把Container::data_type放在模板参数列表里

template <class Container, class DataType = Container::data_type>
concept CanPutData = requires (DataType d, Container a)
{
  put(d, a);
};

Demo

这种形式的好处是当requires-clause比较大时,如果Container没有data_type成员,编译器只会报模板参数列表不满足约束,rather than output the entire requires clause.