std::string& 类型的非类型模板参数可以在 gcc 中编译,但不能在 clang 中编译

Ale*_*lex 19 c++ language-lawyer c++20

我正在使用此处列出的书籍学习 C++ 。特别是,我了解到我们不能用作std::string非类型模板参数。现在,为了进一步明确我对这个主题的概念,我尝试了以下示例,该示例在 gcc 和 msvc 中编译,但在 clang 中不编译。演示

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  
}
Run Code Online (Sandbox Code Playgroud)

我的问题是哪个编译器就在这里(如果有的话)。也就是说,程序是格式良好的还是 IFNDR。

Col*_*mbo 14

Clang 抱怨你的模板参数是一个子对象。(如果将参数设置为完整的字符串对象,则它可以工作。)

此行为基于 [temp.arg.nontype] 标准中的早期限制,其中读取

对于引用或指针类型的非类型模板参数,常量表达式的值不应引用(或对于指针类型,不应是以下地址):

  • 子对象 (6.7.2 [intro.object]),

从 C++20 中的P1907起,此限制已取消,但 Clang 尚未反映这一点。当您将版本 10 与 C++17 一起使用时,GCC 也会失败:

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