I am teaching myself the new concepts feature of C++20 and I hit a snag when I was trying to ensure that the member function that has to be present only accepts specific types. I found this question which showed me how to ensure any function can be present. Then I wanted to take it a step further by ensuring a function with specific parameters are present. I started by defining that the type T
must have a function number()
that returns an int
#include <concepts>
template <typename T>
concept MyRequirement = requires (T t)
{
{ t.number(int) } -> std::same_as<int>;
};
template <typename T>
requires MyRequirement<T>
struct RequiresBool
{
T t;
};
struct GoodType
{
int number(int x) { return x; };
};
int main()
{
RequiresBool<GoodType> good_object;
}
but gcc gave me the following error:
<source>:7:16: error: expected primary-expression before 'int'
7 | { t.number(int) } -> std::same_as<int>;
| ^~~"
So I changed it to the following which worked.
template <typename T>
concept MyRequirement = requires (T t, int x)
{
{ t.number(x) } -> std::same_as<int>;
};
However, when I change the function signature in GoodType
to int number(double x)
, it still works. Sure, a double
can be implicitly converted to an int
and this would also work for normal functions. I could get around this by declaring (but not defining) int number(double);
in GoodType
which would give me an error during compilation, but this puts the responsibility on whoever writes the template class to remember to do this.
This works fine with other types, e.g.
template <typename T>
concept MyRequirement = requires (T t, std::string x)
{
{ t.number(x) } -> std::same_as<int>; //int number(int x) is now invalid
};
but the integers/doubles give me a headache.
Is some way ensure that the type of x in MyRequirement
HAS to be an integer using C++20 concepts?