繁体   English   中英

Constexpr和模板:编译器错误?

[英]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编译器的错误吗?
  • 是否有标准/明智的解决方法来规避此错误?

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM