I have the following code using concepts:
struct bar {
void foo() {}
};
template <typename T>
concept Fooable = requires (const T& t) { // const bar& t doesn't support t.foo()
{ t.foo() };
};
template <typename Fooable>
void callfoo(Fooable bar)
{
bar.foo();
}
int main()
{
bar b;
callfoo(b);
return 0;
}
I would expect the code not to compile as bar
does not support calling foo()
on a const instance. However it does compile fine - link.
The parameter list description on cppreference isn't much helpful in this regard:
parameter-list - a comma-separated list of parameters like in a function declaration, except that default arguments are not allowed and it cannot end with an ellipsis (other than one signifying a pack expansion). These parameters have no storage, linkage or lifetime, and are only used to assist in specifying requirements. These parameters are in scope until the closing } of the requirement-seq.
Am I misunderstanding what the cv-qualifiers are for in a requires expression parameter list? Am I missing something entirely? I am further confused by cppreference having some examples making use of universal reference parameters so there must be some point in it.
I am using gcc9
with -fconcepts
(though gcc trunk and clang with concepts on godbolt are fine with this code as well so don't assume it's compiler related).
You have a bug in your callfoo
function. You are using a typename, not a concept. Change the declaration to either
template <Fooable Foo>
void callfoo(Foo bar)
or
void callfoo(Fooable auto bar)