C++26 constexpr placement new 详解:编译期管理对象生命周期
本文是「C++26 新特性单篇精讲」系列第 14 篇。阅读约需 5 分钟,文末可跳转完整合订本。
一、是什么
C++26 允许在constexpr函数中使用 placement new,即在已分配内存上构造对象:
new(ptr)T(args)这原本只能在运行时使用,现在编译期代码也能管理对象生命周期。
二、为什么需要它
编译期算法有时需要管理对象生命周期,例如自定义容器、内存池、字符串构造等。C++26 之前, placement new 不能在constexpr中使用,限制了编译期代码的表达能力。
三、完整代码示例
#include<utility>constexprintmake_in_buffer(){alignas(int)unsignedcharbuf[sizeof(int)];int*p=new(buf)int(42);intvalue=*p;p->~int();// 手动析构returnvalue;}static_assert(make_in_buffer()==42);intmain(){}编译期 vector 雏形
#include<utility>template<typenameT,std::size_t N>classconstexpr_vector{alignas(T)unsignedchardata_[sizeof(T)*N];std::size_t size_=0;public:constexprvoidpush_back(constT&value){new(data_+size_*sizeof(T))T(value);++size_;}constexpr~constexpr_vector(){for(std::size_t i=0;i<size_;++i){reinterpret_cast<T*>(data_+i*sizeof(T))->~T();}}};四、编译器支持与特性测试宏
| 编译器 | 版本 |
|---|---|
| GCC | 15+ |
| Clang | 19+ |
| MSVC | 19.50+ |
#if__cpp_constexpr_dynamic_alloc>=202211L#endif五、常见陷阱
- 必须手动析构:placement new 不会自动调用析构函数;
- 内存必须对齐:使用
alignas(T)保证对齐; - 不能返回指向局部缓冲的指针:否则会产生悬空引用。
六、小结
constexprplacement new 让编译期代码可以构造复杂对象,是静态反射和编译期容器的重要基础设施。
- 返回 C++26 新特性全景合订本: C++26 新特性全景解析
- C/C++ 后台架构学习社区,欢迎关注:https://github.com/0voice
本文基于 C++26 已批准特性撰写,具体实现以编译器文档为准。