[英]Constexpr and templates: compiler bug?
预期的工作如下:
#include <array>
constexpr std::array<int, 3> values = {1, 2, 3};
template <int i> struct A { static constexpr int val = values[i]; };
int main() { A<1> a; }
但是,如果我们使用values.size()
作为模板参数, values.size()
从MSVC编译器收到编译器错误:
int main() { A<values.size()> a; }
错误是表达式没有求出常量 。 GCC编译没有错误。
MSVC是正确的。 在任何constexpr上下文中都不能有未定义的行为。 否则,这不是一个常量表达式。
该行:
int main() { A<values.size()> a; }
基本上是:
constexpr auto i = values[values.size()];
哪个越界。 实际上,MSVC可以正确诊断错误:
example.cpp <source>(3): error C2131: expression did not evaluate to a constant C:/msvc/v19_16/include\\array(187): note: failure was caused by out of range index 3; allowed range is 0 <= index < 3 <source>(4): note: see reference to class template instantiation 'A<3>' being compiled <source>(2): note: see reference to class template instantiation 'std::array<int,3>' being compiled Compiler returned: 2
另一方面,GCC和MSVC都接受以下代码:
int main() { A<values.size() - 1> a; }
这实际上是GCC的错误/缺陷,而不是MSVC。
A<values.size()> a;
由于有效索引为[0, size())
导致您访问的values
超出范围。 MSVC给您一个错误,它无法执行此操作,因为它是未定义的行为,并且常量表达式中不允许这样做。
请注意,c也可以正确诊断并发出错误: https : //godbolt.org/z/vmi86S
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.