如何复制boost :: aligned_storage对象中的数据?

时间:2018-09-21 13:23:01

标签: c++ boost memcpy

boost::aligned_storage数据类型对我很有用,以便在c ++ 11之前的环境中提供对齐的存储。我有一个包含此存储成员的类:

template <size_t StoreSize>
class RoutineStorage {
   enum { ROUTINE_STORAGE_SIZE = StoreSize};
   enum { BUFFER_ALIGNMENT_VALUE = 8 };

   template <typename TStorageType> TStorageType& getStorageAsType()
   {
       BOOST_STATIC_ASSERT_MSG(boost::has_trivial_assign<TStorageType>::value &&
         boost::has_trivial_copy<TStorageType>::value,
         "The storage type must be trvially copyable and assignable to support this classes "
          "copy|assign semantics.");
        ... // Checking and some other code.
        return new (_store.address()) TStorageType();
   }

private:
    typedef boost::aligned_storage<ROUTINE_STORAGE_SIZE, BUFFER_ALIGNMENT_VALUE> 
        StorageBuffer;

    StorageBuffer _store;
}

我想为此类提供一个复制构造函数,但是当我查看aligned_storage的实现时,它有一个复制构造函数列为private和注释// noncopyable。关于这种类型的任何增强页面似乎都没有对此的解释,所以我得出结论,他们不想处理不同可能的模板化缓冲区大小的复制。我怀疑以下方法适合复制此缓冲区:

RoutineStorage(const RoutineStorage<StoreSize>& copy)
{
    std::memcpy(_store.address(), copy._store.address(), _store.size())
}

这会不会有问题?据我所知,aligned_buffer address函数将给出连续内存地址的开始,而size将使我始终复制正确的大小。

1 个答案:

答案 0 :(得分:1)

就像复制缓冲区一样

RoutineStorage(const RoutineStorage<StoreSize>& copy)
{
    std::memcpy(_store.address(), copy._store.address(), _store.size())
}

还不够。是的,您将拥有一个精确的副本,但实际上您没有在该StorageBuffer中创建的对象。 [intro.object]\1声明

  

C ++程序中的构造创建,销毁,引用,访问和操作对象。当隐式更改联合的活动成员([class.union])或创建临时对象([conv.rval)时,将通过定义([basic.def]),new-expression创建对象。 ],[class.temporary])。

因此,在将对象复制到store并放置新的位置之前,实际上并没有对象,只是存储。

可以说您正在存储Foo。最初,您会像这样在Foo中创建StorageBuffer

Foo* f = new(_store.address()) Foo();

因此,在复制构造函数中,您只需要调用Foo的复制构造函数,并将其放入_store中,就像

RoutineStorage(const RoutineStorage<StoreSize>& copy)
{
    f = new(_store.address()) Foo(copy.*f);
}