Does C++ define the behavior of the following code:
template <class T>
concept C = true;
struct C {};
template <C T>
struct A {};
template <struct C T>
struct B {};
int main() {
// when using MSVC
C c; // error
bool b = C<int>; // also error
// and can't use concept C anywhere other
// than the template parameter list
constexpr struct C cc {};
struct C c2; // ok
A<int> a; // ok
A<cc> a; // error
B<cc> b; // ok
return 0;
}
Can anyone answer me:
template <struct C T>
struct B {};
I found this on cppreference:
When used as a template argument, class T is a type template parameter named T, not an unnamed non-type parameter whose type T is introduced by elaborated type specifier
If you have any template (other than a function template with overloads), you cannot have anything else in the same scope with the same name.
So that means your declaration template <class T> concept C
means that you can have no other entity named ::C
. This is defined as ill-formed, so the C++ standard says this code should not compile.
Your issue does appear if one is introduced via an inline namespace:
template <class T>
concept C = true;
inline namespace x {
struct C {};
}
Now, struct C
will refer to the struct x::C
, and there is no way to unambiguously refer to the concept.