Subject: [boost] aligned_storage in unions
From: dherring_at_[hidden]
Date: 2010-09-17 11:11:35


Hi,

While C++0x promises to change things (see draft spec section 9.5), C++
currently does not allow unions to contain members having a nontrivial
constructor, operator=, or destructor. This excludes std::string,
std::complex, structures containing either, etc.

The "standard" workaround is to allocate your own memory and use manual
type casting. Boost::aligned_storage can be used to maintain proper
alignment, but it cannot be placed inside a union due to the default ctor,
dtor, and noncopyable functions. Thus I am forced to use part of
boost::detail.

Here is a simple example.

#include <boost/type_traits/aligned_storage.hpp>

// define a union-safe wrapper
template <class T> struct UnWrap
{
   boost::detail::aligned_storage::aligned_storage_imp<
     sizeof(T), boost::alignment_of<T>::value> space;

   T * get() const { return static_cast<T *>(space.address()); }
   T * operator->() const { return get(); }
   T & operator*() const { return *get(); }
};

union U
{
   UnWrap<std::string> s;
   int x;
};

U u;
new (u.s.get()) std::string;
*u.s="hi";

Questions:
- Is there a better way to do this?
- Am I doing something blatantly wrong?
- Could aligned_storage_impl be exposed for such uses? (AIUI,
   the detail namespace contains unsupported internals.)

Thanks,
Daniel