模板非类型参数

template non type arguments

本文关键字:类型参数      更新时间:2023-10-16

$14.3.2-"…非类型、非模板模板参数的模板参数应为以下之一:

常数表达式(5.19(,指定具有静态存储持续时间和外部或内部链接的对象的地址,或具有外部或内部链接的函数。。。">

在下面显示的代码中,我无法理解为什么不允许将"name2"answers"name3"作为非类型模板参数。我在Windows上使用的是gcc 4.7.2。

"name2"answers"name3"都是数组的名称,因此都是常量表达式。此外,"name2"具有内部链接,"name3"同时具有静态链接和内部链接。

template<char const *p> void f()
{
}
char name1[] = "Hi";
static char name2[]= "Hi";
const static char name3[]= "Hi";
char *name4 = "Hi";
int main()
{
    f<name1>();
    f<name2>();
    f<name3>();
    f<name4>();
}

正如@Nawaz正确猜测的那样,这是一个实现错误,而不是标准中一个深奥的角落。

具体来说,gcc似乎有问题。除了最后一个违反标准的name4,它的其余部分都可以用clang 编译。

我认为问题在于,您使用的表达式实际上不是指针,而是数组,指针衰减仅适用于name1。正如@KonradRudolph在评论中指出的那样,这很可能是一个编译器错误,C++11标准的14.3.2节允许它,name1name2name3之间没有本质上的区别。

作为一种变通方法,以下内容将使用-std=c++11:与GCC 4.7.2一起编译

template<char const *p> void f()
{
}
char name1[] = "Hi";
static char name2[]= "Hi";
const static char name3[]= "Hi";
int main()
{
    f<(char const*)&name1>();
    f<(char const*)&name2>();
    f<(char const*)&name3>();
}

在C++98模式中,它不会编译,因为强制转换的结果从来都不是常量表达式,而在C++11中,它可能是。