非模板参数限制有哪些?
非模板参数限制有哪些?
本文多数摘自http://www.csdn.net 的一篇问答。本人对模板参数的限制还不是很了解,只是在学习过程中认为这些意见和问题对我的学习很有帮助,摘录在此。如有不同意见,欢迎留言,共同探讨。谢
最近看《C++Templates 完全引导》是遇到一个很迷惑不解的问题,
在书P.40、P.110中
template <char const* name>
class MyClass {
…
};
char const* s = "hello";
MyClass<s> x; // ERROR: s is pointer to object with internal linkage
这里"hello"是个内部链接(internal linkage)对象
但是:
template <char const* name>
class MyClass {
…
};
extern char const s[] = "hello";
MyClass<s> x; // OK
(1) "hello"是字符串常量,因为不是“变量”,所以没有内部、外部链接属性。
有内部外部链接属性的是那个s。
(2) C++规定,有const修饰的变量,不但不可修改,还都将具有内部链接属性,也就是只在本文件可见。(这是原来C语言的static修饰字的功能,现在const也有这个功能了。)又补充规定,extern const联合修饰时,extern将压制const这个内部链接属性。于是,extern char cosnt s[]将仍然有外部链接属性,但是还是不可修改的。
(3) 1.char const* s = "hello";
MyClass<s> x; // ERROR: s is pointer to object with internal linkage
我不知道lz标注的error信息是怎样得到的,在vs2005下的错误信息是:
invalid template argument for 'MyClass', expected compile-time constant expression
主要原因在于template是在编译时就生成的,而s是一个指针变量,它的值是运行时可知。
(4) 一下这段话是原作者的感悟,本人有些不是很理解,但是也暂时摘录在此。
nontype template parameters要求是在编译或者链接时值必须是可知的。对于内部链接对象来说,对于其他编译单元不可见,而在编译期至少模板的实例化是共享的(blue_zyb说的我很认同),但是如果内部链接对象可以作为template argument(模板实参)会发生语义上的错误,例如字符串文字量(如“abcx”,前面我说是字符串常量,这种称法不准确)。他传递给模板的是个指针,而非他的值("abcx").况且如果还有一个"abcx"的话,也是传递的是地址,并且这两个地址从理论上说是不相同的(即使某些编译器会做优化,让其相同)。但是他对我们用户来说不相同。但同时我们要说两个字符串文字量的值是相同的。应该共享一个类的定义(注:这是我们使用者的角度来谈),而实际上编译器无法以值的方式传递这种常量,而以地址的方式传递常量。这样如果编译器生成了不同的类的实现,这就违法了模板给我的信息(相同值的非类型类型『nontype template parameters』模板参数生成的对象是共享一个实例的类的),因此编译器不应该生成相应的类的实现。