Home > Blockchain >  Non type template parameter of type std::string& compiles in gcc but not in clang
Non type template parameter of type std::string& compiles in gcc but not in clang

Time:09-17

I am learning C using the books listed here. In particular, I learnt that we cannot use std::string as a non-type template parameter. Now, to further clear my concept of the subject I tried the following example which compiles in gcc and msvc but not in clang. Demo

std::string nameOk[] = {"name1", "name2"};
template<std::string &name>
void foo()
{
   
}
int main()
{
    
    foo<nameOk[0]>(); //this compiles in gcc and msvc but not in clang in C  20  
}

My question is which compiler is right here(if any). That is, is the program well-formed or IFNDR.

CodePudding user response:

Clang is complaining that your template argument is a subobject. (If you make the argument a complete string object, it works.)

This behavior is based on an earlier restriction in the standard at [temp.arg.nontype], which read

For a non-type template-parameter of reference or pointer type, the value of the constant expression shall not refer to (or for a pointer type, shall not be the address of):

  • a subobject (6.7.2 [intro.object]),

This restriction is lifted as of P1907 which is in C 20, but Clang hasn't reflected that yet. GCC also fails when you use e.g. version 10 with C 17:

error: '& nameOk[0]' is not a valid template argument of type 'std::string&' {aka 'std::__cxx11::basic_string<char>&'} because 'nameOk[0]' is not a variable

CodePudding user response:

Clang is wrong in rejecting the code as this is allowed by the standard. From temp.param#6:

6) A non-type template-parameter shall have one of the following (possibly cv-qualified) types:

6.1) a structural type (see below),

7) A structural type is one of the following:

7.2) an lvalue reference type, or

(emphasis mine)

This means that std::string& can be used as a nontype template parameter for which nameOk[0] is a valid nontype template argument and the program is well-formed.

  • Related