Безопасность размещения new и std :: destroy_at в типизированном std :: array? - PullRequest
1 голос
/ 20 марта 2019

Рассмотрим следующий пример:

#include <array>
#include <memory>

class trivial
{
public:
    trivial() = default;
    trivial(int a, float b) : m_a(a), m_b(b) {}

private:
    int m_a;
    float m_b;
};

template<typename T>
void write(T& arr, size_t idx, int a, float b)
{
    ::new(static_cast<void*>(std::addressof(arr[idx]))) trivial(a, b);
}

template<typename T>
void destroy(T& arr, size_t idx)
{
    std::destroy_at(std::addressof(arr[idx]));
}

int main()
{
    auto arr = std::array<trivial, 20>();

    write(arr, 3, 10, 20.0f);
    destroy(arr, 3);
}

Безопасно ли использовать размещение new и std::destroy_at на месте для произвольных (но разумных) массивов данных?Есть ли здесь какие-либо риски, потенциальное неопределенное поведение или проблемы с переносимостью?Предполагая, что мы не будем пытаться присвоить уничтоженное значение, которое, как я понимаю, не определено.

Я заметил, что этот подход тестирует лучше, чем использование std::aligned_storage и reinterpret_cast, в основном из-за std::launder выступающий в качестве блокировщика оптимизации.Если меня устраивают дополнительные ограничения хранения моих значений в std::array (например, требуется конструктор по умолчанию), это приемлемый вариант использования?

1 Ответ

3 голосов
/ 20 марта 2019

У вас есть двойное уничтожение третьего элемента std::array arr.Один раз - явным уничтожением (вызов destroy), а другим - неявным уничтожением (когда arr выходит из области видимости).Это приводит к неопределенному поведению в соответствии со стандартом C ++.

15,4 Деструкторы [class.dtor]
...
16 Как только деструктор вызывается для объекта, объект больше не существует;поведение не определено, если деструктор вызывается для объекта, время жизни которого закончилось.[Пример: если деструктор для автоматического объекта вызывается явным образом, а затем блок оставляется таким образом, который обычно вызывает неявное уничтожение объекта, поведение не определено.- конец примера]

Пример в приведенной выше цитате несколько похож на то, что вы пытаетесь сделать.

...