ideone linkПодмена экземпляров `std :: aligned_storage`, содержащих типы, не подлежащие тривиальному копированию, - неопределенное поведение?
#include <iostream>
#include <type_traits>
using namespace std;
// Non-trivially-copyable type.
struct NTC
{
int x;
NTC(int mX) : x(mX) { }
~NTC() { cout << "boop." << x << endl; }
};
int main()
{
using AS = aligned_storage_t<sizeof(NTC), alignof(NTC)>;
// Create two `std::aligned_storage` instances
// and "fill" them with two "placement-new-constructed"
// `NTC` instances.
AS as1, as2;
new (&as1) NTC{2};
new (&as2) NTC{5};
// Swap the `aligned_storages`, not their contents.
std::swap(as1, as2);
// Explicitly call `~NTC()` on the contents of the
// aligned storage instances.
NTC& in1{*static_cast<NTC*>(static_cast<void*>(&as1))};
NTC& in2{*static_cast<NTC*>(static_cast<void*>(&as2))};
in1.~NTC();
in2.~NTC();
return 0;
}
ли выше код неопределенное поведение?
Вот что я думаю, что это происходит:
NTC
является нетривиальным-копируемым типом.- Я создаю две ячейки памяти, подходящие для хранения
NTC
объектов (std::aligned_storage
). - Я строю два экземпляра
NTC
непосредственно в ячейки памяти. std::aligned_storage
instances are PODTypes.Это означает, что тип совместим с типами, используемыми на языке программирования C, можно управлять с помощью функций библиотеки C: его можно создать с помощью std :: malloc, его можно скопировать с помощью std :: memmove и т. Д. , и могут быть обменены с библиотеками C напрямую, в двоичной форме.
- Поскольку выровненные экземпляры хранилища являются типами POD, мне должно быть разрешено перемещать/свопировать/копировать их.
- Переустановка выровненных экземпляров хранилища означает, что берет все байты из выровненного хранилища A и свопит их со всеми байтами из выровненного хранилища B.
- Выполнение этого не будет вызывать деструктор/копировать-конструктор объектов, хранящихся внутри,
NTC
. KG
Мои достоинства: Не верно? Если не определено поведение, в какой части программы это происходит? И почему?
Новый потенциально правильно/неправильно информация (gathered from a deleted answer):
std::aligned_storage
довольно много просто ЬурейеЕ для массива C-стиле.std::swap
has an overload for C-style arrays since C++11.- Эта перегрузка calls
std::swap_ranges
, которая свопирует каждый элемент в массив. - Следовательно, замена двух экземпляров
std::aligned_storage
должна менять их содержимое по элементам.
Я делаю какую-либо ошибку в этих новых предположениях?
Первоначально я неправильно читал, и я мог исправить это сразу, но hvd получил его. –