模板编译错误-标准与否
Template compilation error - standard or not?
我有以下代码:
template<int k>
void foo()
{
}
int main(int argc, char* argv[])
{
int k = 1000;
foo<k>();
return 0;
}
不编译,但如果我声明k
为const
,它可以编译:
template<int k>
void foo()
{
}
int main(int argc, char* argv[])
{
const int k = 1000;
foo<k>();
return 0;
}
现在,我明白了为什么在第一种情况下它不能编译而在第二种情况下它可以编译,但是这是标准指定的吗?
得到的错误是:
Error 1 error C2971: 'foo' : template parameter 'k' : 'k' : a local variable cannot be used as a non-type argument
这不是很清楚,因为k
是一个局部变量也在const
的情况下…对吧?
根据标准14.3.2,这必须是一个常量表达式:
非类型、非模板模板形参的模板实参必须是:
- 为整型或枚举类型的整型常量表达式;或
-非类型模板参数的名称;或
-具有外部链接的对象或函数的地址,包括函数模板和函数模板id,但不包括非静态类成员,表示为&id-表达式,其中&如果名称引用函数或数组,或者对应的模板形参是引用,则为可选;或
- 5.3.1中描述的指向成员的指针。
GCC 4.6.2给出一个稍微容易理解的错误:
错误:' k '不能出现在常量表达式
§14.3.2.1(简略)说:
非类型、非模板模板形参的模板实参必须是:
-整型或枚举型的整型常量表达式;
§5.19.1说[删节,强调我的]:
整型常量表达式只能包含字面值、枚举数、const变量或用常量表达式…初始化的整型或枚举类型的静态数据成员。
您对k
的第二个定义满足这一点,因此允许将其用作模板参数的ICE。
这个错误有点误导人,因为"局部变量不能用作非类型参数"通常是正确的,但在某些限制下,它是完全正确的
No。当编译器试图将模板展开为最终形式时,可以在编译时计算Const值。所以执行时的值不能作为模板的参数,但是你总是可以将变量的引用设置为模板参数
template<int& k>
void foo()
{
}
int main(int argc, char* argv[])
{
int k = 1000;
foo<k>();
return 0;
}
相关文章:
- 编译器现在遵循C++14标准,我的项目不再编译神秘的SFML错误
- 如何从标准输入中检测格式化输入错误?
- 张量流错误 此文件需要编译器和库支持 ISO C++ 2011 标准
- 我想获取点的属性,它报告错误 C3867:"point::output_x":非标准语法;使用"&"创建指向成员的指针
- C++标准视窗 SDK 文件中的编译错误
- 提升多精度浮点数128:标准::exp错误:'no matching function for call'
- 常量转发引用给出错误 C2440:"正在初始化":无法从"常量标准::字符串"转换为"常量标准::字符串 &&"
- 分段错误标准::矢量<标准::字符串>
- 从标准::未来<void>到非标量标准::未来<bool>引发的错误转换
- 标准库to_string(双精度)在 vs2015 中给出错误的值.有什么解决办法吗?
- 代码中的 C++ 标准错误
- IOS 目标链接 cocoa 堆栈库,该库写入 C++11 标准错误
- 如何在C++中读取 bash 标准错误
- 如何从库标准错误中读取
- 添加带有自定义标准错误的 fprintf() 语句后,标准输出挂起
- 是否有一种方法可以查看哪个线程正在使用gdb打印标准输出或标准错误?
- 在c# GUI项目上重定向标准输出+标准错误
- 即使重定向了标准输出和标准错误,Unix程序如何在屏幕上显示输出?
- 发送标准错误的可能形式
- 如何从分离的QProcess中读取标准输出/标准错误