c++c++20c++-conceptsrequires-clauserequires-expression

C++ 'requires' with type requirement in class won't compile


This code won't compile on any C++ complaint compiler (Clang, GCC, MSVC):

template<typename T>    
    requires(T t) { typename T::name; }
class MyVector
{    
};

The error(s):

 --- Clang ----
    <source>:9:14: error: 'T' does not refer to a value
        requires(T t) { typename T::name; }
                 ^
    <source>:8:19: note: declared here
    template<typename T>    
                      ^
 --- GCC ----
    <source>:9:16: error: expected primary-expression before 't'
        9 |     requires(T t) { typename T::name; }

 --- MSVC ----
    <source>(9): error C2760: syntax error: 't' was unexpected here; expected ')'
    <source>(9): error C2059: syntax error: ')'

But this will:

template<typename T>    
        requires std::is_integral_v<T>   &&
        requires(T t) { typename T::name; }
class MyVector{};

Interestingly, this will also compile fine!

 template<typename T>    
            requires true   &&
            requires(T t) { typename T::name; }
 class MyVector{};

I am aware concept can be used instead, but was trying requires alone.


Solution

  • requires(T t) { typename T::name; } is a requires-expression.

    However under the template head of a template declaration you can (optionally) put only a requires-clause, not a requires-expression.

    A requires-clause also uses the requires keyword, but in a distinct meaning from that of a requires-expression. A requires-clause has the form requires E where E is an expression formed by conjunction/disjunction of constraint expressions. An atomic constraint can be a requires-expression though:

    template<typename T>    
    requires requires(T t) { typename T::name; }
    

    In both

    template<typename T>    
    requires std::is_integral_v<T>   &&
        requires(T t) { typename T::name; }
    

    and

    template<typename T>    
    requires true   &&
        requires(T t) { typename T::name; }
    

    you are applying the correct syntax. The first requires introduces the requires-clause, the && is a conjunction between individual constraint expression and the second requires introduces a requires-expression as one of the constraint expressions.