Search code examples
c++c++20c++-concepts

Outside class definition of member function enabled with concept


Following this question, I was trying to define a member function enabled by a concept outside the class definition:

template<typename T>
concept MyConcept = std::is_integral<T>::value; //could be anything...

template<typename T>
class F {
public:
    void foo() requires MyConcept<F>;
};

template<typename T>
void F<T>::foo() requires MyConcept<F<T>>
{
    //long implementation...
}

this piece of code works fine on GCC, but fails on MSVC and Clang.

Note that I need that the concept must be satisfied on F<T>, and not only T (my actual code is much more complex and uses variadic templates).

Demo

Clang says:

error: out-of-line definition of 'foo' does not match any declaration in 'F<T>'
void F<T>::foo() requires MyConcept<F<T>>
           ^~~

note: member declaration nearly matches
void foo() requires MyConcept<F>;
     ^

It works fine on Clang if I move the definition inside the class, but not on msvc:

template<typename T>
class F {
public:
    void foo() requires MyConcept<F> 
    {
        //long implementation...
    }
};

In any case, I would like to avoid having long implementations inside class definitions.

What am I doing wrong? How can I define member function enabled with a concept outside the class correctly?


Solution

  • It is a compiler bug.

    • It has been solved on Clang version 16;
    • It is still not solved on Apple Clang;
    • It seems to be solved on MSVC version 19.36.32532.0, although it is still "under consideration" here.

    Note that, for MSVC 19.36.32532.0, in the function definition the requires clause must be the same of the declaration (MyConcept<F> and not MyConcept<F<T>>):

    template<typename T>
    void F<T>::foo() requires MyConcept<F>
    {
        //long implementation...
    }