我可以
std::bitset< 10 > bitsetA;
或
const size_t LengthB = 20;
std::bitset< LengthB > bitsetB;
没有任何问题。
但是,如果长度不是const
size_t LengthC = 30;
std::bitset< LengthC > bitsetC; // Line 30, say
我面临以下编译错误
'LengthC' cannot appear in a constant-expression
template argument 1 is invalid
这是什么原因?
对于编译器和用户代码,如果要接受第30行,会出现什么问题?是因为LengthC可能有一些别名吗?
答案 0 :(得分:7)
模板根据模板参数实例化新类型,这在编译时完成。您无法在运行时实例化新类型,因为C ++是静态类型的。
所以当你有一个非const变量时,它不能作为模板参数传递,因为它不能保证是那个值(你必须“在运行时”实例化一个新的类型“)。只有当它是const时,才能确保该值确实是恒定的,因此可以在模板参数中使用。
答案 1 :(得分:4)
模板参数必须在编译时声明const
,以便模板可以在编译时实例化。
在您给出的示例中,确实看起来LengthC
不会从初始化的位置更改为必须实例化模板的点,因此可以将其视为常量,但编译器没有义务弄清楚这一点。规范说必须声明参数const
,因此不需要进行编译时流控制分析。
答案 2 :(得分:1)
模板是编译时生物 - 变量是运行时生成的。如果需要将变量传递给模板,则需要在运行时执行此操作,例如在模板化类的构造函数中。
答案 3 :(得分:1)
编译器在const
投射时严格。
10
和const size_t LengthB = 20;
都评估为常量。如果没有const
关键字,编译器就无法轻易确定变量是否可能在声明和使用之间发生变化。