gpt4 book ai didi

c++ - 交换包含放置新创建对象的存储缓冲区

转载 作者:太空狗 更新时间:2023-10-29 23:02:16 25 4
gpt4 key购买 nike

我最近看到一段代码,它使用存储缓冲区来创建对象,然后简单地交换缓冲区以避免复制开销。这是一个使用整数的简单示例:

std::aligned_storage_t<sizeof(int), alignof(int)> storage1;
std::aligned_storage_t<sizeof(int), alignof(int)> storage2;

new (&storage1) int(1);
new (&storage2) int(2);

std::swap(storage1, storage2);

int i1 = reinterpret_cast<int&>(storage1);
int i2 = reinterpret_cast<int&>(storage2);

//this prints 2 1
std::cout << i1 << " " << i2 << std::endl;

在一般情况下,这感觉像是未定义的行为(特别是交换缓冲区,然后访问对象,就好像它们仍然存在一样)但我不确定标准对这种存储和新放置的使用有何规定。非常感谢任何反馈!

最佳答案

我怀疑有几个因素导致这个未定义,但我们只需要一个:

[C++11: 3.8/1]: [..] The lifetime of an object of type T ends when:

  • if T is a class type with a non-trivial destructor (12.4), the destructor call starts, or
  • the storage which the object occupies is reused or released.

所有后续使用都是在生命周期结束后使用,这是错误的。

关键是每个缓冲区都被重用。

因此,尽管我希望这在实践中至少适用于普通类型(以及某些类),但它是未定义的。


以下可能可以拯救您:

[C++11: 3.8/7]: If, after the lifetime of an object has ended and before the storage which the object occupied is reused or released, a new object is created at the storage location which the original object occupied, a pointer that pointed to the original object, a reference that referred to the original object, or the name of the original object will automatically refer to the new object and, once the lifetime of the new object has started, can be used to manipulate the new object [..]

...除非您没有创建新对象。

这里可能值得注意也可能不值得注意,令人惊讶的是,随后的隐式析构函数调用都是明确定义的:

[C++11: 3.8/8]: If a program ends the lifetime of an object of type T with static (3.7.1), thread (3.7.2), or automatic (3.7.3) storage duration and if T has a non-trivial destructor, the program must ensure that an object of the original type occupies that same storage location when the implicit destructor call takes place; otherwise the behavior of the program is undefined.

关于c++ - 交换包含放置新创建对象的存储缓冲区,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29132928/

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