Код: Выделить всё
#include
#include
// Type that will get moved
struct NonDestructible {
~NonDestructible() = delete;
};
static_assert(::std::is_copy_assignable_v);
static_assert(::std::is_move_assignable_v);
// A sheddable wrapper that implicitly casts to an rvalue
template
struct Move {
T&& value;
Move(T& what) : value {::std::move(what)} {}
operator T&& () const noexcept { return ::std::forward(value); }
};
// CTAD for readability
template
Move(T&) -> Move;
int main() {
alignas(NonDestructible) char buffer1[sizeof(NonDestructible)] {};
alignas(NonDestructible) char buffer2[sizeof(NonDestructible)] {};
auto t1 = reinterpret_cast(buffer1);
auto t2 = reinterpret_cast(buffer2);
*t1 = ::std::move(*t2);
*t2 = Move(*t1); // ERROR on MSVC: attempts calling ~NonDestructible
return 0;
}
< /code>
Почему этот код не удается на MSVC (v19.latest), при этом скомпилируется на GCC (14.2) и Clang (19.1)? По какой-то причине он пытается вызвать деструктор и, таким образом, терпит неудачу. Ссылка на Godbolt Со сравнением с соответствующими компиляторами < /p>
edit < /h1>
После большого количества возиться, я понял, что MSVC просто отказывается называть неявный оператор T && < /code>, и вместо этого всегда настаивает на вызове воображаемого оператора. Что, возможно, приводит к созданию временного неразрушимого объекта Я решил вручную определить этот оператор const t & , чтобы увидеть, могу ли я хотя бы смягчить временный экзем /> Очевидно, что это не решение, потому что оно не приводит к повышению движения, а скорее в копии. < /p>
Подробнее здесь: https://stackoverflow.com/questions/796 ... struct-c23
Мобильная версия