Reputation: 7709
Is it possible to define a class which is not a class template and that can store (say upon construction) a reference to any particular type and retrieve it later via a getter method?
struct Wrapper {
template<typename T> Wrapper(const T& t): t_(t);
// How to store the reference??
};
Boost::variant
is of course not a solution since its implemented as a class template. And I have no RTTI. (Its in HPC environment, performance is all!)
The getter()
should be able to remember the type. So that auto
can be used later.
Upvotes: 1
Views: 703
Reputation: 473547
The getter() should be able to remember the type.
It can't. You erased the type. That's what happens when you put a value of arbitrary type inside an object of a consistent type. It's called "type erasure": the original type is removed from the containing class.
One of the consequences of this is that the type cannot magically be recovered. You can't have a class that is initialized with a type on a per-instance basis, and then have one of its member functions return a different type based on how that particular instance was initialized.
C++ is a statically typed language. The return type of every function must be defined at compile time. It cannot change because of what you put into a class at runtime.
It can't remember the type.
I can't use RTTI.
Then what you want is a void*
. RTTI is the only way to do recover the original value's type in a type-safe way. If you don't want type-safety, then you want a void*
. All you would be doing is writing a wrapper around static_cast<T*>
.
There's really no point in writing a wrapper around void*
and static_cast
. If that's what you want, and you're willing to accept the perils of using them (ie: breaking the type-system), then just use it. The reason boost::any
exists is to provide a type-safe void*
, so that at least you know when you're casting it wrongly.
Upvotes: 5
Reputation: 10917
boost::any
http://www.boost.org/doc/libs/1_50_0/doc/html/any.html
std::vector<boost::any> many;
int i = 5;
std::string a = "5";
many.push_back(i);
many.push_back(a);
std::string res;
if (many[1].type() == typeid(std::string))
res = boost::any_cast<std::string>(many[1]);
Upvotes: 3