You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何无需宏及已弃用std::aligned_storage实现placement-new对齐存储?

解决方案:无宏、无弃用API的对齐存储实现

要实现符合C++标准、支持类列表传入的placement-new对齐存储,可通过模板元编程计算类型列表的最大大小与对齐要求,结合标准类型构造安全的存储结构,完全替代宏和已弃用的std::aligned_storage。

核心实现思路

  1. 用模板参数包接收目标类列表
  2. 通过元函数计算列表中所有类的最大大小和最大对齐要求
  3. 基于计算结果定义带对齐属性的存储容器
  4. 提供类型安全的对象构造/销毁辅助函数

完整代码实现

通用对齐存储头文件 aligned_buffer.hpp

#pragma once

#include <cstddef>
#include <type_traits>
#include <cstddef>

// 元函数:计算类型列表的最大大小
template <typename... Ts>
struct max_size {
    static constexpr std::size_t value = 0;
};

template <typename T, typename... Ts>
struct max_size<T, Ts...> {
    static constexpr std::size_t value = std::max(sizeof(T), max_size<Ts...>::value);
};

// 元函数:计算类型列表的最大对齐
template <typename... Ts>
struct max_align {
    static constexpr std::size_t value = 1;
};

template <typename T, typename... Ts>
struct max_align<T, Ts...> {
    static constexpr std::size_t value = std::max(alignof(T), max_align<Ts...>::value);
};

// 元函数:检查类型是否在目标列表中(C++11兼容)
template <typename T, typename... Ts>
struct type_in_list : std::false_type {};

template <typename T, typename... Ts>
struct type_in_list<T, T, Ts...> : std::true_type {};

template <typename T, typename U, typename... Ts>
struct type_in_list<T, U, Ts...> : type_in_list<T, Ts...> {};

// 对齐存储主模板
template <typename... Ts>
struct aligned_buffer {
    // 预计算的存储参数
    static constexpr std::size_t storage_size = max_size<Ts...>::value;
    static constexpr std::size_t storage_align = max_align<Ts...>::value;

    // 对齐的字节数组存储
    alignas(storage_align) std::byte data[storage_size];

    // 类型安全的对象构造(placement-new封装)
    template <typename T, typename... Args>
    T* emplace(Args&&... args) {
        static_assert(type_in_list<T, Ts...>::value, "Type not allowed in this buffer");
        return new(data) T(std::forward<Args>(args)...);
    }

    // 对象销毁封装
    template <typename T>
    void destroy(T* obj) {
        static_assert(type_in_list<T, Ts...>::value, "Type not allowed in this buffer");
        obj->~T();
    }
};

// 简化使用的类型别名
template <typename... Ts>
using aligned_buffer_t = aligned_buffer<Ts...>;

适配自定义类列表

在你的业务头文件中,只需引入通用头并传入目标类列表即可生成专属存储类型:

// my_target_classes.hpp
#pragma once

// 引入通用对齐存储
#include "aligned_buffer.hpp"

// 自动生成或手动定义的类
class GeneratedClassA { /* ... */ };
class GeneratedClassB { /* ... */ };
class CustomClass { /* ... */ };

// 生成适配这些类的对齐存储别名
using my_aligned_buffer = aligned_buffer_t<GeneratedClassA, GeneratedClassB, CustomClass>;

业务代码中使用

#include "my_target_classes.hpp"

int main() {
    my_aligned_buffer buffer;

    // 构造对象
    GeneratedClassA* obj_a = buffer.emplace<GeneratedClassA>(/* 构造参数 */);
    CustomClass* obj_c = buffer.emplace<CustomClass>(123, "test");

    // 使用对象...

    // 销毁对象
    buffer.destroy(obj_a);
    buffer.destroy(obj_c);

    return 0;
}

关键优势

  • 标准合规:完全基于C++11及以上标准特性,未使用宏或已弃用的std::aligned_storage
  • 类型安全:通过静态断言限制仅允许列表内的类型构造,避免错误
  • 灵活适配:类列表通过模板参数传入,自动生成的类只需加入参数包即可适配
  • 易用性:封装了placement-new和析构逻辑,减少手动操作的出错风险

内容的提问来源于stack exchange,提问作者Jeff G

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 20:25:15