Boost logo

Boost :

Subject: Re: [boost] aligned_storage in unions
From: Larry Evans (cppljevans_at_[hidden])
Date: 2010-09-17 11:34:48


On 09/17/10 10:11, dherring_at_[hidden] wrote:
> 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

Hi Daniel,

Why not use boost::variant<std::string,int>?
Using your example:

  boost::variant<std::string,int> u;
  u = "hi";
  assert(u.which()==1);
  u = 9;
  assert(u.which()==2);

(I may have the which results off by one,
but you get the idea).

-regards,
Larry


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