结合sizeof和placement new是否安全?

Rob*_*son 2 c++ templates placement-new c++11

考虑以下课程:

template <class T>
class defer {
public:
    template <class ...Args>
    void construct(Args&&...);
    T& obj();
    ~defer();
private:
    std::uint8_t memory[sizeof(T)];
    T * ptr();
};

template <class T>
template <class ...Args>
void defer<T>::construct(Args&& ...args) {
    new(static_cast<void*>(&memory[0])) T(std::forward<Args>(args)...);
}

template <class T>
T& defer<T>::obj() {
    return *(ptr());
}

template <class T>
defer<T>::~defer() {
    ptr()->~T();
}

template <class T>
T * defer<T>::ptr() {
    return static_cast<T*>(&memory[0]);
}
Run Code Online (Sandbox Code Playgroud)

现在我知道这有问题,但为了使代码简短以便讨论,我们假设在对象超出范围之前总是调用defer :: construct().

话虽这么说,这样做总是安全吗?或者可以在一些奇怪的角落中多个虚拟继承与其他疯狂的情况下std :: uint8_t [sizeof(T)]没有分配足够的空间?

Use*_*ess 12

R. Martinho Fernandes打败了我!使用

typename std::aligned_storage<sizeof(T)>::type  memory;
Run Code Online (Sandbox Code Playgroud)

而你很高兴.详情请见此处.


正如我们的评论员小组指出的那样,默认对齐方式总是足够的,但可能比您的类型要求严格(因此您可以通过额外的填充来浪费空间).您可以通过明确指定它来避免这种情况:

typename std::aligned_storage<sizeof(T), alignof(T)>::type memory;
Run Code Online (Sandbox Code Playgroud)

  • 那么`aligned_storage <sizeof(T),alignof(T)>`?没什么大不了的,但是在"T"不需要默认(最大)对齐的情况下可能会节省填充. (2认同)