0

Based on this old stack overflow question How do you define a C++ concept for the standard library containers?

I see that it's possible to define a concept for STL containers. However, I am unsure how to actually apply the concept to anything, because it requires 2 containers, container a and container b.

For example, taking the signature of the most upvoted answer

template <class ContainerType> 
    concept Container = requires(ContainerType a, const ContainerType b) 

I've only seen concepts used with just 1 requirement argument, like so

//source: https://en.cppreference.com/w/cpp/language/constraints
template<typename T>
concept Hashable = requires(T a)
{
    { std::hash<T>{}(a) } -> std::convertible_to<std::size_t>;
};
 
struct meow {};
 
// Constrained C++20 function template:
template<Hashable T>
void f(T) {}
//
// Alternative ways to apply the same constraint:
// template<typename T>
//     requires Hashable<T>
// void f(T) {}
//
// template<typename T>
// void f(T) requires Hashable<T> {}
 
int main()
{
    using std::operator""s;
 
    f("abc"s);    // OK, std::string satisfies Hashable
    // f(meow{}); // Error: meow does not satisfy Hashable
}
康桓瑋
  • 33,481
  • 5
  • 40
  • 90
Shisui
  • 1,051
  • 1
  • 8
  • 23

1 Answers1

1

The definition of this concept is in fact

 template <class ContainerType> 
 concept Container = /* */;

which only constrains one type ContainerType, so the function that applies this concept would be

 template <Container C>
 void f(C& c);
康桓瑋
  • 33,481
  • 5
  • 40
  • 90
  • Thanks! But where is a and const b coming from? – Shisui Mar 11 '22 at 06:41
  • 1
    They come from the parameters of the requires clause, which means that when there is an instance `a` of type `ContainerType` and an instance `b` of type `const ContainerType&`, they need to satisfy the following constraint expressions – 康桓瑋 Mar 11 '22 at 06:44
  • Would the concept only be evaluated if both ```a``` and ```b``` were present? What if you only had ```a``` of type ```ContainerType``` but no ```b```? – Shisui Mar 11 '22 at 06:46
  • 1
    This has nothing to do with instances, concepts apply to types. when `ContainerType` is instantiated as a specific type, concept needs to check whether the expression in the requires clause is satisfied. – 康桓瑋 Mar 11 '22 at 06:49
  • Or `template requires Container void f(C&& c);` or `void f(Container auto&& c);`.... – JHBonarius Mar 11 '22 at 07:51