Home > Software design >  Concepts: require a function on a type without default constructing that type
Concepts: require a function on a type without default constructing that type

Time:04-08

I need to require of some type A that there exists a function f(A, A::B).

I'm testing that by calling f with instances of A and A::B. Is there a less ostentatious way to test against an instance of the dependent type without requiring default constructible?

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;
}

CodePudding user response:

Same way you're already getting a Container without requiring that one to be default constructible: by just sticking it in the parameter list of the requires expression:

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

CodePudding user response:

You can also put Container::data_type in the template parameter list

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

Demo

The advantage of this form is that when the requires-clause is relatively large, if the Container does not have a data_type member, the compiler will only report that the template parameter list does not satisfy the constraints, rather than output the entire requires clause.

  • Related