为什么需要std :: aligned_storage?

Aer*_*Sun 12 c++ std c++11

因此,正如我未正确指出的那样,std :: aligned_storage的主要优点是它可以管理对齐.它也可以用memcpy复制.它也仅适用于POD类型.

但!

1)POD类型默认从编译器接收一些对齐,我们可以通过#pragma pack(push,1)删除对齐

2)我们可以默认使用memcpy复制POD(我们不应该为此功能做点什么)

所以我实际上无法获得我们需要std :: aligned_storage的目的?

小智 14

std::aligned_storage只要您希望将内存分配与对象创建分离,就可以使用它.

你声称:

它也仅适用于POD类型.

但是这是错误的.没有什么可以防止std::aligned_storage与非POD类型一起使用.

cppreference上的示例提供了一个合法的用例:

template<class T, std::size_t N>
class static_vector
{
    // properly aligned uninitialized storage for N T's
    typename std::aligned_storage<sizeof(T), alignof(T)>::type data[N];
    std::size_t m_size = 0;
...
Run Code Online (Sandbox Code Playgroud)

这里的想法是,一旦static_vector构造了,就会立即为N类型的对象分配内存T,但是还没有T创建类型的对象.

你不能用一个简单的T data[N];数组成员做到这一点,因为这会立即运行T每个元素的构造函数,或者如果T不是默认构造的话,甚至不会编译.

  • 请注意未来的读者,`std::aligned_storage` 和朋友在 C++23 中已被弃用:https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p1413r3.pdf (4认同)

asc*_*ler 7

首先,#pragma指令不可移植。该标准没有定义任何必须支持的强制编译指示,因此每个编译器都可以自由定义自己的集合。但是std::aligned_storage无论您使用什么编译器,都需要简单地工作。编译器库编写者可能会根据编译指示、属性或编译器扩展来定义它,但用户可以直接#include <type_traits>开始使用它。

并且“它仅适用于 POD 类型”是不正确的。事实上,一种常见的使用方式aligned_storage是作为一块内存,可以手动创建和销毁任何类型的其他对象。它或类似的东西可以用来实现像std::optionaland 之类的东西std::variant

为了展示这背后的想法,这里开始编写一个类似于以下内容的类std::optional

#include <type_traits>
#include <memory>

template <typename T>
class my_optional
{
private:
    std::aligned_storage_t<sizeof(T), alignof(T)> m_storage;
    bool m_valid;
public:
    constexpr my_optional() noexcept : m_valid(false) {}
    constexpr my_optional(const T& obj)
        noexcept(std::is_nothrow_copy_constructible<T>::value)
        : m_valid(false)
    {
        new(static_cast<void*>(&m_storage)) T(obj);
        m_valid = true;
    }
    constexpr const T& operator*() const
    {
        return *static_cast<const T*>(static_cast<const void*>(&m_storage));
    }
    constexpr T& operator*()
    {
        return *static_cast<T*>(static_cast<void*>(&m_storage));
    }
    ~my_optional()
    {
        if (m_valid)
            operator*().~T();
    }
    // Much more, to obey the Rule Of Five and add more functionality...
 };
Run Code Online (Sandbox Code Playgroud)


Lin*_*gxi 5

std::aligned_storage管理对齐存储。无论您在存储中放置 POD 还是非 POD 对象都无关紧要。

目的std::aligned_storage是它提供了一个标准化的更高级别的实用程序来管理对齐存储,以便您可以编写更干净的代码,减少麻烦。