Итак, как говорится в заголовке, мне интересно, как правильно перемещать элемент в массиве, например:
std::array<std::aligned_storage_t<sizeof(T), alignof(T)>, N> data;
Это так же просто, как делать:
data[dst] = data[src];
Или мне нужно добавить что-то еще, например, перемещение, поскольку его хранилище не инициализировано, нужно ли мне использовать конструкторы копирования или перемещения, например:
new (&data[dst]) T(std::move(data[src]));
Поскольку данные [src]неправильный тип T, мне нужно вместо этого сделать:
new (&data[dst]) T(std::move(*std::launder(reinterpret_cast<T*>(&data[src])));
Я ищу наиболее гибкий способ перемещения элемента для всего, что может быть T, включая перемещение только типов и т. д.
По сути, я создаю упакованный массив, который всегда перемещает элементы, чтобы они были смежными в памяти, даже если они удалены, чтобы предотвратить дыры в активной части массива.
Редактировать: По желанию комментариевминимальный пример, я думаю, что-то вроде:
template<class T, std::size_t N>
class SimpleExampleClass {
std::array<std::aligned_storage_t<sizeof(T), alignof(T)>, N> data;
public:
void move_element(std::size_t src, std::size_t dst) {
// data[dst] = data[src]; ?
// or
// new (&data[dst]) T(std::move(data[src]));
// or
// new (&data[dst]) T(std::move(*std::launder(reinterpret_cast<T*>(&data[src])));
// or
// something else?
// then I would need some way to clean up the src element, not sure what would suffice for that.
// as calling a destructor on it could break something that was moved potentially?
}
// Other functions to manipulate the data here... (example below)
template<typename ...Args>
void emplace_push(Args&&... args) noexcept {
new (&data[/*some index*/]) T(std::forward<Args>(args)...);
}
void push(T item) noexcept {
emplace_push(std::move(item));
}
};