gpt4 book ai didi

c++ - 为什么这里需要 std::launder ?

转载 作者:行者123 更新时间:2023-12-04 13:25:32 26 4
gpt4 key购买 nike

我正在阅读 cppreference 并在 std::aligned_storage 的示例中有一个 vector/数组类的例子:

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];
// IF you want to see possible implementation of aligned storage see link.
// It's very simple and small, it's just a buffer

std::size_t m_size = 0;

public:
// Create an object in aligned storage
template<typename ...Args> void emplace_back(Args&&... args)
{
if( m_size >= N ) // possible error handling
throw std::bad_alloc{};

// construct value in memory of aligned storage
// using inplace operator new
new(&data[m_size]) T(std::forward<Args>(args)...);
++m_size;
}

// Access an object in aligned storage
const T& operator[](std::size_t pos) const
{
// note: needs std::launder as of C++17
// WHY
return *reinterpret_cast<const T*>(&data[pos]);
}

// Delete objects from aligned storage
~static_vector()
{
for(std::size_t pos = 0; pos < m_size; ++pos) {
// note: needs std::launder as of C++17
// WHY?
reinterpret_cast<T*>(&data[pos])->~T();
}
}
};
本质上,每个元素所在的每个存储区/区域/内存地址都是一个字符缓冲区。在每个存在的元素位置,在 T 类型的缓冲区中完成一个新的放置。因此,当返回该缓冲区的位置时,可以将 char 缓冲区强制转换为 T*,因为在那里构造了一个 T。为什么从 C++17 开始需要 std::launder?我已经问了很多关于这个的问题,似乎同意:
alignas(alignof(float)) char buffer [sizeof(float)];
new (buffer) float;// Construct a float at memory, float's lifetime begins
float* pToFloat = buffer; // This is not a strict aliasing violation
*pToFloat = 7; // Float is live here
这显然不是严格的别名违规,完全没问题。那么为什么这里需要 std::launder 呢?

最佳答案

    // note: needs std::launder as of C++17
return *reinterpret_cast<const T*>(&data[pos]);

Why is std::launder required from C++17 onwards?


您可以从 reinterpret_cast 取消引用指针的条件是最小的。这不是其中的一个。您正在将指向一种类型的指针转​​换为指向完全不相关类型的指针,并通读它。见 here . std::launder允许您派生有效的指针。存在的全部理由就是给你这个。
在 C++17 之前,您必须保存从 Placement new 返回的指针,因为它是唯一有效的指向 T 的指针。就在眼前,之前 std::launder你不能从缓冲区制作一个。

I have asked a bunch of questions about this and it seems agreed that... This is not a strict aliasing violation apparently, it's completely fine. So therefore why is std::launder required here?


出于同样的原因,这不好。也没有人同意这很好。请参阅@eerorika 在 your question here 上的回答.

关于c++ - 为什么这里需要 std::launder ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68869404/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com