c++ - 结合使用 sizeof 和 placement new 是否安全?

标签 c++ templates c++11 placement-new

考虑以下类:

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]);
}

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

话虽这么说,这样做总是一定安全吗?或者在一些奇怪的多重虚拟继承的极端情况下,std::uint8_t[sizeof(T)] 是否可以分配足够的空间?

最佳答案

R。 Martinho Fernandes 击败了我!使用

typename std::aligned_storage<sizeof(T)>::type  memory;

然后你就可以开始了。参见 here了解详情。


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

typename std::aligned_storage<sizeof(T), alignof(T)>::type memory;

关于c++ - 结合使用 sizeof 和 placement new 是否安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13072379/

相关文章:

c++ - 如何为 Solaris 和 HP-AIX 定义 _FILE_OFFSET_BITS & _LARGE_FILES 宏

c++ - 根据参数类型中是否存在 POD 结构成员专门化模板函数

c++ - g++:用闭包类型初始化的 std::function 总是使用堆分配?

c++ - std::ios::openmode 的组合在文件存在时截断但阻止创建新文件?

C++ - 返回 const unique_ptr

c++ - 使用 static_cast 转换 POD 对象

c++ - 使用 std::vector 作为 std::map 的键在未找到和使用 reserve() 时不返回 end()

c++ - 有人可以向我解释以下模板代码吗?

c++ - 传递 operator== 以在 C++ 中设置

c++ - 为什么 as_const 的 const&& 重载被删​​除了?