char* 具有内部链接,因此它不能不是非类型模板参数



一些我不理解的代码:

template<const char *T>
class A
{
};
const char *arr="hello world";
int main()
{
    A<arr> obj;
}

此代码段无法编译。

visual studio编译器的错误消息为:

Invalid template argument for 'A', expected compile-time constant expression

g++的错误消息为:

'arr' is not a valid template argument because 'arr' is a variable , not the address of a variable

对于visualstudio编译器,即使在我将const更改为constexpr之后,该代码仍然无法编译。

为什么?这与内部链接外部链接++模板这本书,但不明白为什么以及如何)

此外,将const char *arr = "Hello world";更改为

const char arr[] = "Hello world";

external const char *arr="Hello world";

不会起作用。

这会起作用external const char arr[]="Hello world";

这个问题比您所做的要简单。Visual Studio编译器的错误消息实际上非常清楚。arr不是有效的模板参数,因为它不是编译时常数。

为了使用字符串作为模板非类型参数,它必须是一个具有外部链接的变量(尽管我相信C++11确实删除了这一要求——请参阅Columbo的回答)。因此,您可以将代码更改为以下内容,这样就可以工作了:

template <const char* T>
class A
{
   // ...
};
extern const char arr[] = "hello world";
int main()
{
    A<arr> obj;
}

请注意arr的声明是如何更改的。该变量现在是一个具有外部链接的命名对象,因此可以用作模板非类型参数。

基本上,它的地址被传递到模板。这意味着决定其唯一性的不是字符串的内容,而是对象本身。换句话说,如果有两个不同的变量持有完全相同的字符串,那么它们将具有不同的类型,并创建模板类的两个不同实例。

指针类型的模板参数不允许引用字符串文字([temp.arg.notype]/(1.3))。相反,请声明一个全局数组:

constexpr char arr[] = "hello world"; // Or use const only, but won't be able to
                                      // use it inside the template

这可以用作模板参数,因为它可以出现在常量表达式中,并且具有静态存储持续时间,使其成为常量表达式([expr.const]/5)的允许结果。

最新更新