Peter Olcott said:
Is there anyway of doing this besides making my own string from scratch?
union AnyType {
std::string String;
double Number;
};
If you really want to union the memory footprint of types with non-trivial
constructors, you could wrap them in a container which has a trivial
constructor. Unfortunately, this will currently not yield very portable code
as you won't have any control over alignment, but it will probably work on
most platforms:
#include <string>
template<class T> class UnionMember
{
public:
void construct()
{ new (*this) T(); }
template<class P1> void construct (const P1 & p1)
{ new (*this) T(p1); }
template<class P1, class P2> void construct (const P1 & p1, const P2 &
p2)
{ new (*this) T(p1, p2); }
// etc.
void destroy() { (*this)->~T(); }
operator T * () { return reinterpret_cast<T*>(m_data); }
operator const T * () const { return reinterpret_cast<const
T*>(m_data); }
T * operator -> () { return operator T*(); }
const T * operator -> () const { return operator const T*(); }
private:
char m_data[sizeof(T)]; // for true portable code you'll need to align
this buffer to meet the alignment requirements for T.
};
union MyUnion
{
UnionMember<std::string> myString;
double myDouble;
};
int main()
{
MyUnion u;
// construct a string within the union
u.myString.construct("hi there");
// assign it with a different string
*u.myString = "goodbye";
// assign the double - don't forget to destroy the string first!
u.myString.destroy(); // destroy the string
u.myDouble = 34.5; // and assign the double.
}
You should take care to construct every object on it's first use and
destruct it before using another value in the union, or when you dispose of
the union.
The next C++ standard revision will most probably include methods of
retrieving and controlling alignment of datamembers.
- Sylvester