重新解释转换模板非类型参数:clang c ++ 14 vs c ++ 1z [英] Reinterpret cast a template non-type parameter: clang c++14 vs c++1z
问题描述
请考虑以下代码:
template <int* > struct foo { };
int main() {
foo<(int*)42> f;
(void)f;
}
在clang 3.8.0上使用 -std = c ++ 11
或 -std = c ++ 14
,程序编译。当使用 -std = c ++ 1z
编译时,会出现以下错误:
When compiling on clang 3.8.0 with -std=c++11
or -std=c++14
, the program compiles. When compiling with -std=c++1z
, it errors with:
main.cpp:4:9: error: non-type template argument is not a constant expression
foo<(int*)42> f;
^~~~~~~~
gcc 5.3.0不编译代码不管C ++模式,我相信是正确的。 C ++ 14和C ++ 1z之间的clang有什么区别,为什么它接受代码?
gcc 5.3.0 does not compile the code regardless of C++ mode, which I believe to be correct. What is the difference in clang between C++14 and C++1z and why does it accept the code? Did something change in C++1z that is relevant here?
推荐答案
使用 godbolt 演示在 -std = c ++ 1z
模式中Clang 3.5.1接受代码,但3.6 .0拒绝它。 changelog 表示此版本是在支持for C ++ 1z特性,即对所有非类型模板参数的常量求值。我的猜测是,C ++ 11和C ++ 14模式使用C ++ 11规则,而C ++ 1z模式使用C ++ 1z /最新的规则草案。当然,程序在C ++ 11/14模式下被视为有效的事实本身就是一个错误。
Using godbolt demonstrates that in -std=c++1z
mode Clang 3.5.1 accepts the code but 3.6.0 rejects it. The changelog indicates that this version was when support for C++1z features were added, namely "Constant evaluation for all non-type template arguments". My guess is that C++11 and C++14 mode use the C++11 rules while C++1z mode uses the C++1z/latest draft rules. Of course, the fact that the program is considered valid in C++11/14 mode is a bug in of itself.
这里有一些类似的错误报告不直接相关)案例:
Here are some bug reports with similar (but not directly related) cases:
错误18043 - 允许任意地址常量表达式作为非类型模板参数作为扩展
Bug 10398 - Clang不会接受空指针常量作为非类型模板参数
错误10396 - clang在名称变异期间作为非类型模板参数崩溃
这篇关于重新解释转换模板非类型参数:clang c ++ 14 vs c ++ 1z的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!