c++c++20c++-conceptsrequires-expression

cv qualifiers in concept requires expression parameter list


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).


Solution

  • 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)