交换包含非平凡可复制类型的 std::aligned_storage 实例 - 未定义的行为?

Swapping `std::aligned_storage` instances containing non-trivially-copyable types - undefined behavior?

ideone link

#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;
}

上面的代码是未定义的行为吗?

这是我认为正在发生的事情:

我的观点是否不正确?如果确实发生了未定义的行为,它发生在程序的哪一部分?为什么?


新增potentially-correct/incorrect信息(gathered from a deleted answer):

我在这些新假设中有什么错误吗?

在将不可平凡复制的类型放入缓冲区后直接访问缓冲区的字节是一个非常糟糕的主意,但还不是未定义的。

作为 NTC 交换后尝试访问缓冲区违反了别名规则,[basic.lval]p10:

If a program attempts to access the stored value of an object through a glvalue of other than one of the following types the behavior is undefined:

(10.1) -- the dynamic type of the object,

[....]

通过 memcpy 或等价物复制可简单复制的类型意味着保留动态类型。对于非平凡可复制的类型没有这样的暗示,所以在交换之后,你不再有任何 NTC 对象可以访问。