Reputation:
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)?
Upvotes: 18
Views: 987
Reputation: 302787
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()
.
Upvotes: 21