4

I'm writing a C++ concept for unordered associative containers namely std::unordered_map. I'm having difficulty detecting the erase function (also insert but lets ignore that for the moment).

Here's my concept attempt, sadly it fails when I try calling a templated function requiring it.

template <class _ContainerType_>
concept InsertErasable = requires(_ContainerType_ a)
{
    { a.erase( _ContainerType_::const_iterator) } -> typename _ContainerType_::iterator;
};

I use it like so:

template<InsertErasable _ContainerType_>
inline void Test123( const _ContainerType_& container )
{
    return;
}

std::unordered_map<std::string, int> map;
::Test123(map);

error C7602: 'Test123': the associated constraints are not satisfied

Using latest Visual Studio 2019.

It should detect the first erase signature shown here: https://en.cppreference.com/w/cpp/container/unordered_map/erase

Any idea what I am doing wrong?

user176168
  • 1,294
  • 1
  • 20
  • 30
  • 1
    Please [don't use identifiers beginning with an underscore followed immediately by an uppercase letter](https://stackoverflow.com/a/228797/5376789). – xskxzr Mar 03 '20 at 03:47

1 Answers1

3

Honestly i never used concepts in practice but i managed to figure out what is wrong here. The code within a require clause must be an expression, not a half expression, half definition of a function. In other words, it must be an expression that would compile if you placed it inside of a regular function (https://en.cppreference.com/w/cpp/language/constraints section on require clauses). To fix your issue you must adjust the code inside of the concept clause to be a valid C++ expression. This can be done in one of two ways. Either:

template <class _ContainerType_>
concept InsertErasable = requires(_ContainerType_ a)
{
    {a.erase(a.cbegin())} -> typename _ContainerType_::iterator;
};

or

template <class _ContainerType_>
concept InsertErasable = requires(_ContainerType_ a,_ContainerType_::const_iterator b)
{
    {a.erase(b)} -> typename _ContainerType_::iterator;
};

Example on compiler explorer

Adam
  • 41
  • 3