返回static constexpr vector的const引用函数是否合法?编译差异及选型疑问
问题解答
1. 代码的行为是否定义良好?
这段代码不具有定义良好的行为,核心原因是:
- 在C20和C23标准中,
std::shared_ptr的构造函数并非constexpr,无法在constexpr上下文中构造实例。尽管C26标准计划引入constexpr版本的std::shared_ptr,但当前主流标准(C20/23)并不支持该特性。 - GCC 13.2.0能编译通过,是因为它提前实现了部分C++26的实验性特性,这属于编译器的非标准扩展,不具备跨编译器的可移植性。
2. MSVC编译失败的原因
你的MSVC版本(19.41.34123.0,对应VS 2022 17.11)严格遵循C++20/23标准,拒绝构造constexpr std::shared_ptr是符合标准的正确行为,并非编译器对constexpr vector支持不足。cppreference提到的MSVC支持constexpr vector,指的是存储普通类型(比如int)的vector,而非包含std::shared_ptr这类非constexpr友好类型的vector。
3. 写法可行性与两种版本的对比
static constexpr版本:在C20/23标准下完全不可行,属于不符合标准的写法,仅能在部分提前实现C26特性的编译器上通过,不具备工程上的可移植性。static const std::vector<std::shared_ptr<Bar>> empty版本:这是符合C++11及以后标准的合法写法,具备以下特性:- 线程安全:C++11规定静态局部变量的初始化是线程安全的,无需额外同步逻辑。
- 仅初始化一次:第一次进入该分支时完成初始化,后续调用直接返回引用,性能开销极低。
- 行为明确:完全符合标准,在所有主流编译器上都能正常工作。
两者不存在优劣对比的前提,因为constexpr版本在当前标准下不合法,实际工程中只能选择static const版本。
内容的提问来源于stack exchange,提问作者Jane Doe
相关产品推荐
相关产品推荐

