5

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:

  1. Is this declaration correct ?
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

  1. As mentioned above, can I define a concept and a class type with the same name? If the answer is yes, how do I specify that the name is a concept?
ValueError
  • 53
  • 4

1 Answers1

3

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.

Artyer
  • 31,034
  • 3
  • 47
  • 75