字符串作为模板参数

4
尽管C++标准不允许使用字符串字面值作为模板参数,但是这样的内容是被允许的:
《ISO/IEC 14882:2011》中提到:
14.3.2 模板非类型参数 [temp.arg.nontype]
2 [注:字符串字面值(2.14.5)不满足任何这些类别的要求,因此不是可接受的模板参数。[示例:
template class X { / ... / }; X x1; // 错误:将字符串字面值作为模板参数 const char p[] = "Vivisectionist"; X x2; // 正确
--end example]--end note]
那么为什么下面的代码在所有编译器中都会给我一个错误呢?(gcc 4.7.2,MSVC-11.0,Comeau)
template <const char* str>
void foo() {}

int main()
{
   const char str[] = "str";
   foo<str>();
}

+1 它曾经可以使用类似于 MSCV 6 或 7 的东西。但上次我尝试时,它不再编译 :-( 很高兴你问这个问题。 - Stephane Rolland
2个回答

5

向前回溯几行。

14.3.2/1: 一个常量表达式(5.19),它指定具有静态存储期和外部或内部链接的对象的地址。


4

你是对的,去掉 const 有帮助。但是,我认为这只是演示了编译器在处理常量时存在的一个错误,因为 const char p[]="" 仍然定义了一个外部对象。 - jpalecek
1
根据n.m.的引用,它需要是一个具有“静态存储期和外部或内部链接”的对象(因此,除非const使其具有非静态存储期,否则理论上应该可以工作,无论它是外部还是内部链接)。不过我太懒了,不想弄清楚const如何影响这一切。但我认为这是编译器的错误,因为标准的示例代码失败了:http://ideone.com/YQNCfB。 - Cornstalks
@JamesKanze:那么14.3.2/1呢:“一个常量表达式(5.19),它指定了具有静态存储期和外部或内部链接的对象的地址”? - Cornstalks
@Cornstalks 在C++03和C++11之间有一个变化。C++03要求模板参数具有外部链接;C++11(我想)也允许内部链接。由于一般来说,我们还不能指望使用C++11,所以最好只使用外部链接。 - James Kanze
1
@Cornstalks,C++03要求外部链接,而命名空间作用域中的const具有内部链接。这不是编译器错误(但可以认为它是标准中的错误)。 - James Kanze
显示剩余7条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接