模板非类型参数

时间:2013-01-07 09:18:35

标签: c++ templates c++11 arguments linkage

  
    

$ 14.3.2 - “...非类型非模板模板参数的模板参数应为以下之一:

  
     

...一个常量表达式(5.19),用于指定具有静态存储持续时间和外部或内部链接的对象的地址或具有外部或内部链接的函数...“

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

'name2'和'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>();
}

2 个答案:

答案 0 :(得分:5)

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

具体来说,gcc似乎遇到了麻烦。除非违反标准的最后name4,其余部分与clang

编译良好。

答案 1 :(得分:3)

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

作为一种解决方法,以下将使用-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中它可能是。