ritter
ritter

Reputation: 7709

C++ wrapper class that stores an arbitrary reference, but itself is not a class template

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

Answers (2)

Nicol Bolas
Nicol Bolas

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

log0
log0

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

Related Questions