std::initializer_list能否用于constexpr?GCC与Clang存在编译分歧
关于constexpr初始化std::initializer_list的编译问题
先来看你给出的代码:
#include <initializer_list> int main(){ constexpr std::initializer_list<char> chars{'a','b','c'}; }
为什么Clang会报错?
核心原因是C++标准对std::initializer_list的constexpr构造支持有版本限制。在C20之前,std::initializer_list的构造函数并没有被标记为constexpr——也就是说,编译器没办法在编译阶段完成这个对象的构造。所以如果你的Clang编译器是基于C17或更早版本的标准编译这段代码,必然会抛出错误,典型的错误信息大概是:
error: constexpr variable 'chars' must be initialized by a constant expression
note: non-constexpr constructor 'initializer_list::initializer_list' cannot be used in a constant expression
为啥VC++会输出无意义错误?
这属于VC自身的实现问题,它对constexpr initializer_list的处理逻辑有非标准的地方,导致错误提示完全没抓住重点,不用纠结这个提示,咱们还是按C标准来梳理问题就好。
怎么解决这个问题?
给你两个可行的方案:
- 升级到C++20及以上版本:如果项目允许的话,编译时指定对应标准(比如Clang用
-std=c++20),C++20已经正式把std::initializer_list的构造函数设为constexpr了,代码就能正常通过编译。 - 兼容旧标准的替代方案:如果必须用C++17或更早版本,要么去掉constexpr改成普通const变量:
要是你确实需要编译时可用的字符序列,更推荐用constexpr数组替代:#include <initializer_list> int main(){ const std::initializer_list<char> chars{'a','b','c'}; }#include <array> int main(){ constexpr std::array<char, 3> chars{'a','b','c'}; // 想要类似initializer_list的访问方式,用chars.data()就能拿到首指针 }
内容的提问来源于stack exchange,提问作者NoSenseEtAl
相关产品推荐
相关产品推荐

