C ++模板参数有哪些要求?

时间:2009-03-13 17:27:34

标签: c++ templates parameters const extern

如果您在C ++中使用一个以整数值作为参数的模板,那么对于用作参数的整数变量是否有任何要求与变量在函数调用中用作参数的要求不同?

这是问题here的后续行动。我特别想解决如果WRT变量声明为函数或模板的“extern const int”的差异吗?

我可以看到,对于某些模板情况,编译时需要参数值。这总是如此吗?有没有办法指定(可能仅用于参数值的某些用途)该值是否在运行时使用?

3 个答案:

答案 0 :(得分:13)

以下内容来自标准。

14.3.2.1:

  

非类型非模板模板参数的模板参数应为以下之一:

     
      
  • 整数或枚举类型的整数常量表达式;或
  •   
  • 非类型模板参数的名称;或
  •   
  • 具有外部链接的对象或函数的地址,包括函数模板和函数template-id,但不包括非静态类成员,表示为& id-expression其中&如果名称引用函数或数组,或者相应的template-parameter是引用,则是可选的;或
  •   
  • 指向成员的指针,如5.3.1所述。
  •   

5.19.1:

  

在一些地方,C ++要求表达式计算为整数或枚举常量:作为数组边界(8.3.4,5.3.4),作为case表达式(6.4.2),作为位字段长度(9.6),作为枚举器初始值设定项(7.2),作为静态成员初始值设定项(9.4.2),以及作为整数或枚举非类型模板参数(14.3)。

 constant-expression:
            conditional-expression
     

一个整数常量表达式只能包含文字(2.13),枚举数,常量变量或用常量表达式(8.5)初始化的整数或枚举类型的静态数据成员,整数或枚举类型的非类型模板参数,以及sizeof表达式。浮动文字(2.13.3)只有在转换为整数或枚举类型时才会出现。只能将转换类型转换为整数或枚举   可以使用类型。特别是,除了sizeof表达式外,不应使用函数,类对象,指针或引用,也不得使用赋值,递增,递减,函数调用或逗号运算符。

关于你以前的帖子,我相信“const变量... 初始化 with ......”这一部分的本质(我不认为初始化外部计数)。

答案 1 :(得分:4)

它必须是一个完整的常量表达式。这由5.19的标准文件解释:

  

一个整数常量表达式只能包含文字(2.13),枚举数,常量变量或用常量表达式(8.5)初始化的整数或枚举类型的静态数据成员,整数或枚举类型的非类型模板参数,以及sizeof表达式。浮动文字(2.13.3)只有在转换为整数或枚举类型时才会出现。只能使用转换为整数或枚举类型的转换。

请注意,“integral”是“整数”的另一个术语,但与“int”不同。例如,“char”具有整数/整数类型,但显然不是int类型。具体来说,允许以下内容

  • 10 or 10L or anything like that
  • enum { THIS, OR, THAT };
  • int const this_one = 10;
  • sizeof(char)
  • 当然,任何其他模板参数如上所述

其中任何一个都可以用作具有相应类型的整数类型的参数的模板参数。仍然会应用一些转换。因此,如果它想要一个int并且你传递一个char,它会自动将char提升为int。如果您提供枚举器并且它想要一个int,则相同。

所以按照这些规则,如果你有

extern const int SomeName;

并没有看到使用整数常量表达式初始化该常量的定义,它不能用作模板参数。但它当然可以用作函数参数。那些不需要在编译时知道,因为它们不是类型的一部分。在命名模板特化时,您使用的参数将成为类型的一部分:

MyGreatStack<int, 4> // 4 is now part of the type MyGreatStack<int, 4>!

请注意,SomeName作为参数传递的其他方法。但是,所有这些都可以被整数模板参数接受。您可以通过参考参数接受上述参数,例如

template<const int& V> struct NowItWorks { };

它会接受上面的SomeName。现在,选择了整个程序中唯一的特定位置(因为变量具有extern链接),而不是值。

答案 2 :(得分:3)

在编译时需要int的值。

由于每个模板实例化都是一个单独的编译代码(即使对于整数模板参数),整数在编译时也必须可用(并且必须保证永远不会改变)。

这也是为什么在您要使用大量唯一值时不使用整数模板参数的好主意 - 您可以快速获得一个巨大的可执行文件。