非types的模板参数

我明白,非types模板参数应该是一个常数积分expression式。 有人可以解释为什么这样吗?

template <std::string temp> void foo() { // ... } 
 error C2993: 'std::string' : illegal type for non-type template parameter 'temp'. 

我明白什么是一个不变的整数expression式。 什么原因不允许非常量types如std::string在上面的代码片段?

你不能这样做的原因是因为非常量expression式在编译期间不能被parsing和replace。 他们可能会在运行时更改,这将需要在运行时生成一个新的模板,这是不可能的,因为模板是编译时的概念。

以下是标准允许的非模板参数(14.1 [temp.param] p4):

非types的模板参数应该具有以下(可选的cv-qualified)types之一:

  • 整数或枚举types,
  • 指向对象或指向函数的指针,
  • 左值引用对象或左值引用函数,
  • 指向成员的指针,
  • std::nullptr_t

这是不允许的。

但是,这是允许的:

 template <std::string * temp> //pointer to object void f(); template <std::string & temp> //reference to object void g(); 

C ++标准(2003)中的§14.1/ 6,7,8。


插图:

 template <std::string * temp> //pointer to object void f() { cout << *temp << endl; } template <std::string & temp> //reference to object void g() { cout << temp << endl; temp += "...appended some string"; } std::string s; //must not be local as it must have external linkage! int main() { s = "can assign values locally"; f<&s>(); g<s>(); cout << s << endl; return 0; } 

输出:

 can assign values locally can assign values locally can assign values locally...appended some string 

你需要能够破解模板参数

 template <std::string temp> void f() { // ... } f<"foo">(); f<"bar">(); // different function!? 

现在,impl需要为std::string或者其他任意用户定义的类创build一个唯一的字符序列,存储一个特定的值,其含义对于实现是不知道的。 另外,任何类对象的值都不能在编译时计算。

计划考虑允许文本类types作为后C ++ 0x的模板参数types,这些types由常量expression式初始化。 这些可能会被数据成员recursion地根据它们的值(例如,我们可以应用深度优先,从左到右的遍历)对基类进行修改而被破坏。 但是绝对不能用于任意类。

在模板参数列表中提供的非types模板参数是一个可以在编译时确定其值的expression式。 这样的论点必须是:

常量expression式,具有外部链接的函数或对象的地址,或静态类成员的地址。

此外,string文字是具有内部链接的对象,因此您不能将它们用作模板参数。 你也不能使用全局指针。 考虑到舍入误差的明显可能性,浮点文字是不允许的。