std::construct_at如何实现支持常量表达式的默认初始化?
结论
可以实现,C23标准库已经提供了原生支持,C20环境也可以自己实现符合常量表达式要求的版本。
具体说明
std::construct_at不传参数时的行为是值初始化(等价于::new (p) T()),和你需要的默认初始化(等价于::new (p) T)的核心差异是:对于内置类型、没有用户提供的默认构造函数的类类型,值初始化会执行零初始化,而默认初始化会保留未初始化状态。
方案1:直接使用C++23标准库工具
C++23已经新增了标准库函数std::default_construct_at,完全匹配你的需求:
- 语义等价于
::new (p) T的默认初始化 - 原生支持常量表达式场景
- 无需额外自定义实现
方案2:C++20环境自定义实现
C++20已经允许在常量表达式中使用布置new,你可以自己实现对应函数:
#include <type_traits> #include <memory> template<std::default_initializable T> constexpr T* default_construct_at(T* p) noexcept(std::is_nothrow_default_constructible_v<T>) { return ::new (const_cast<void*>(static_cast<const volatile void*>(p))) T; }
该实现和std::construct_at的异常安全性、常量表达式支持能力完全一致,唯一区别就是执行默认初始化而非值初始化。
注意事项
默认初始化仅对满足std::default_initializable<T>约束的类型合法,对于没有默认构造函数的类型无法使用该操作。
内容的提问来源于stack exchange,提问作者geza
相关产品推荐
相关产品推荐

