首页 > 解决方案 > Consexpr 和模板:编译器错误?

问题描述

以下按预期工作:

#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()模板参数,我会从 MSVC 编译器中得到一个编译器错误:

int main() { A<values.size()> a; }

错误是表达式没有计算为常量。GCC 编译没有错误。

标签: c++templatesconstexpr

解决方案


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; }

推荐阅读