I am trying to write very simple Any object, which can hold object of any type. I want it use inside container, to achieve heterogeneous container.
#include <iostream>
#include <vector>
#include <string>
struct Any
{
template < typename T >
Any(const T & t)
:p(new storageImpl<T>(t)) { }
~Any()
{
delete p;
}
struct storage
{
virtual ~storage() {}
};
template <typename T>
struct storageImpl : storage
{
storageImpl(const T & t) : data(t) {}
T data;
};
template <typename T>
T & get()
{
storageImpl<T> * i = static_cast<storageImpl<T>*>(p);
return i->data;
}
storage * p;
};
usage
int main ()
{
//block1
Any copy(Any(std::string("foo")));
std::cout << copy.get<std::string>();
//block2
std::vector<Any> cont;
cont.push_back(Any(5));
cont.push_back(Any(37.9f));
std::cout << cont[0].get<int>();
std::cout << cont[1].get<float>();
}
I have problem with copy-construction.
When I push Any into vector (//block2), the unnamed Any gets destroyed, so pointer gets deleted, and pushed object is no longer valid.
So I have 2 questions:
1, How to write copy constructor for class Any?
2, Why isn’t unnamed Any in block1 destroyed, so its pointer isn’t deleted?\
EDIT
I have tried
template <typename T>
Any(const Any & rhs)
:p(new storageImpl<T>(rhs.get()))
{
}
but it doesn’t get triggered.
Anyis not a template class. Trying to template the copy-constructor astemplate <typename T> Any(const Any & rhs)is meaningless.What you could do is to use the virtual constructor idiom, to let the
storageImplcopy itself. This is also the method used in Boost.Any.Notice that this implementation have a lot of problems, e.g. the
get()method won’t check whether the Any is really holding a T. It is still better to use a well-tested library e.g. Boost.Any.Copy elision.