11

$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>();
}
4

2 回答 2

5

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

具体来说,gcc 似乎遇到了麻烦。除了最后一个name4违反标准的之外,其余的都可以用clang编译

于 2013-01-07T10:07:02.537 回答
3

我认为问题在于您使用的表达式实际上不是指针而是数组,并且指针衰减仅适用于name1. 这很可能是编译器错误,正如@KonradRudolph 在评论中指出的那样,C++11 标准的第 14.3.2 节允许它,并且name1,name2name3.

作为一种解决方法,以下将使用 GCC 4.7.2 编译-std=c++11

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 中它可能是。

于 2013-01-07T10:12:39.687 回答