数组引用作模板实参:GCC/Clang可编译,MSVC报错,谁符合C++标准?
关于C++模板引用参数在constexpr中使用的编译器行为问题
我正在学习C++的模板与constexpr特性,编写了一段代码,该代码可在GCC和Clang编译器下正常编译,但在MSVC中编译失败。代码如下:
#include <cstddef> template<std::size_t N, const bool (&ref)[N]> void func() { constexpr int j = ref[0]; //被MSVC拒绝,但可通过Clang和GCC编译 } int main() { static constexpr bool arr[] = {true, false}; func<2, arr>(); }
MSVC的错误信息为:
<source>(5): error C2131: expression did not evaluate to a constant <source>(9): note: failure was caused by unevaluable pointer value <source>(10): note: see reference to function template instantiation 'void func<2,& bool const * const `main'::`2'::arr>(void)' being compiled
请问根据C++标准,哪个编译器的行为是正确的?
结论
GCC和Clang的行为符合C++标准,MSVC的行为不符合。
标准依据
根据C++标准相关规则:
- 当模板参数为引用类型且绑定到
static constexpr数组时,该引用属于常量表达式的组成部分。 - 在
constexpr变量初始化中,访问该引用指向的数组元素(ref[0])是合法操作:arr是static constexpr对象,其存储期覆盖整个程序生命周期,地址固定且元素值为编译期可知的常量表达式,因此ref[0]完全满足常量表达式的要求。 - MSVC错误地将绑定到
static constexpr对象的引用地址判定为“不可求值的指针值”,但实际上这类引用在编译期是可完全解析的,访问其元素属于标准允许的常量表达式操作。
内容的提问来源于stack exchange,提问作者user20562802
相关产品推荐
相关产品推荐

