c++ - 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 编译没有错误。
- 这是 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; }
推荐阅读
- node.js - Discord Bot 错误未处理PromiseRejectionWarning
- javascript - 如何将画布保存为.png?(在 laravel 中)
- sql - 在sql查询中获取上个月的数据
- algorithm - 无符号除法算法中的溢出检测
- java - 如何从回收视图中停止回收视图?
- scala - ZIO 1.0.3 改变了环境的工作方式,现在 http4s Blaze 将无法运行
- php - var_dump 返回 null。登录页面给出一个空白页面
- php - FancyTree - 如何放入数据内容生成 php 目录
- java - 在不使用 Maven 的情况下将 JAXB 库包含到 JAR 文件中
- javascript - 在 node.js 中运行时未定义要求