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

Conceptualized `operator auto` in C++20


Starting from C++20 we can precede auto keyword with the name of the concept to limit possible types. And in particular this combination is possible in class conversion operator auto, e.g.

template <typename T> concept x = true;

struct S
{
    operator x auto() { return 2; }
    operator auto() { return 1; }
};

int main() { return S{}.operator x auto(); }

But Clang is the only compiler that accepts the whole program, however main() returns 1 (and not 2 as I would expected), demo: https://gcc.godbolt.org/z/b16jYGa81

GCC accepts the struct definition, but refuses to compile S{}.operator x auto().

And MSVC refuses to accept even struct S with the error:

error C2535: 'S::operator auto(void)': member function already defined or declared

Just wonder, which of the compilers is right here (if any)?


Solution

  • This conversion function:

    operator auto() { return 1; }
    

    Means exactly the same as this converison function:

    operator int() { return 1; }
    

    We're deducing the return type from 1, this isn't a function template.


    This conversion function:

    operator x auto() { return 2; }
    

    Means roughly the same thing as:

    operator int() { static_assert(x<int>); return 2; }
    

    We're deducing the return type from 2 and ensuring that that type (int) satisfies a particular concept (x).


    Putting both together, we have two functions (neither is a function template), both of which are named operator int(), and that's just not allowed. This should be ill-formed even at the point of declaration since the name operator int() is bound to two conflicting declarations.

    Note that the second one is still named operator int(), not operator x auto().