C++类模板constexpr构造函数与非constexpr Wrapped类型规则问询
Wrapper类模板相关问题解答
首先给出示例代码:
template <typename Wrapped> class Wrapper { public: template <typename... Ts> constexpr Wrapper(Ts&&... ts) : wrapped(std::forward<Ts>(ts)...) { } private: Wrapped wrapped; };
1. 非constexpr类型的Wrapped作为模板参数的标准规定
C++标准对该场景的规则如下:
constexpr构造函数本身支持运行期调用,因此只要你不在常量表达式上下文中使用Wrapper的构造函数,哪怕Wrapped是非constexpr类型,模板实例化和使用都是完全合法的,不会触发编译错误。- 模板的constexpr成员遵循「按需实例化、实例化时检查合法性」的规则:只有当你尝试在常量表达式上下文(比如初始化
constexpr变量、静态断言条件、模板参数等场景)中调用该构造函数时,才会要求Wrapped是字面类型,且你传入参数对应的Wrapped构造函数是constexpr的,此时才会触发编译检查,不符合要求才会报错。 - 不同C标准版本对字面类型的范围有所扩充,比如C20开始支持constexpr动态内存分配,
std::string、std::vector等类型也可用于constexpr上下文,但上述规则本身不随标准版本变化。
2. 去掉构造函数的constexpr声明的影响
- 最核心的影响是彻底丧失了在常量表达式上下文中创建
Wrapper实例的能力:哪怕Wrapped本身是支持constexpr构造的字面类型,你也无法用该构造函数初始化constexpr变量,或者在其他需要常量表达式的场景中使用Wrapper实例。 - 对于普通运行期使用的场景,不会产生任何影响,功能、运行性能都和带constexpr声明的版本完全一致。
内容的提问来源于stack exchange,提问作者vojana
相关产品推荐
相关产品推荐

