将sizeof和placement new组合起来是安全的吗? [英] Is it safe to combine sizeof and placement new?

查看:182
本文介绍了将sizeof和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()总是在对象超出范围之前调用。

NOW I KNOW that there are issues with this, but in order to make the code short for purposes of discussion we are going to assume that the defer::construct() is always called before the object goes out of scope.

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

That being said, is it always necessarily safe to do this? Or can in some weird corner case of multiple virtual inheritance with other craziness can std::uint8_t[sizeof(T)] not allocate enough space?

推荐答案

R。马丁霍费尔南德斯打败了我!使用

R. Martinho Fernandes beat me to it! Use

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

有关详情,请参见此处

我们的评论员们指出,默认对齐方式总是足够,但可能比您的类型所需的更严格()。 )。你可以通过明确指定它来避免这种情况:

As our panel of commentators has pointed out, the default alignment is always enough, but may be more stringent than required for your type (so you waste space with extra padding). You can avoid this by just specifying it explicitly:

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

这篇关于将sizeof和placement new组合起来是安全的吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆