Boost logo

Boost :

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


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk