Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/139.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ std::aligned\u存储的目的是什么?_C++_C++11_Std - Fatal编程技术网

C++ std::aligned\u存储的目的是什么?

C++ std::aligned\u存储的目的是什么?,c++,c++11,std,C++,C++11,Std,如果我理解正确,std::aligned_存储的主要优点是它管理对齐。它还可以与memcpy()一起复制,并可与POD类型一起使用 但是 1) 默认情况下,POD类型由编译器对齐,我们可以使用#pragma pack(push,1) 2) 默认情况下,我们可以使用memcpy()复制POD(我们不应该为这个功能做任何事情) 所以我真的不明白为什么我们需要std::aligned_storage?只要您希望将内存分配与对象创建分离,就可以使用std::aligned_storage 你声称: 此外

如果我理解正确,std::aligned_存储的主要优点是它管理对齐。它还可以与
memcpy()
一起复制,并可与POD类型一起使用

但是

1) 默认情况下,POD类型由编译器对齐,我们可以使用
#pragma pack(push,1)

2) 默认情况下,我们可以使用
memcpy()
复制POD(我们不应该为这个功能做任何事情)


所以我真的不明白为什么我们需要
std::aligned_storage

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

你声称:

此外,它仅适用于POD类型

但事实并非如此。没有任何东西阻止
std::aligned_storage
与非POD类型一起使用

提供合法的用例:

模板
类静态向量
{
//为N T正确对齐的未初始化存储
typename std::aligned_storage::type data[N];
std::size\u t m\u size=0;
...
这里的想法是,一旦构建了
静态_向量
,内存将立即分配给
N
类型为
T
的对象,但尚未创建类型为
T
的对象

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

首先,
#pragma
指令是不可移植的。该标准没有定义任何必须支持的强制pragma,因此每个编译器都可以自由定义它有自己的一套。但是无论您使用的是什么编译器,都需要使用
std::aligned_存储
。编译器库编写者可以根据pragmas、属性或编译器扩展来定义它,但用户只需
#包含
并开始使用它即可

事实上,使用对齐存储的一种常见方式是将其作为一块内存,在其中可以手动创建和销毁任何类型的其他对象。它或类似的东西可以用来实现和

为了展示其背后的思想,下面开始编写一个类似于
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...
 };
#包括
#包括
模板
我的课程是可选的
{
私人:
标准::对齐存储\u t m\u存储;
布尔m_有效;
公众:
constexpr my_optional()noexcept:m_valid(false){
constexpr my_可选(const T&obj)
noexcept(std::is\u nothrow\u copy\u constructible::value)
:m_有效(错误)
{
新的(静态铸造和存储)T(obj);
m_valid=true;
}
常量表达式常量T&运算符*()常量
{
返回*static_cast(static_cast(&m_storage));
}
constexpr T&运算符*()
{
返回*static_cast(static_cast(&m_storage));
}
~my_可选()
{
如果(m_有效)
运算符*().~T();
}
//更重要的是,要遵守五原则并添加更多功能。。。
};

std::aligned_storage
管理对齐的存储。是否在存储中放置POD或非POD对象无关紧要


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

。另一种选择是
char[]
但这将/可能不会正确对齐,因为语言无法知道您想要在其中构建什么样的内容。所有这些都回答了OP的“疑问”:
#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...
 };