存储任意引用的C ++包装类,但它本身不是类模板

时间:2012-08-04 19:12:14

标签: c++ c++11 wrapper

是否可以定义一个不是类模板的类,并且可以存储(比如在构造时)对任何特定类型的引用并稍后通过getter方法检索它?

struct Wrapper {
  template<typename T> Wrapper(const T& t): t_(t);

  // How to store the reference??
};

Boost::variant当然不是解决方案,因为它是作为类模板实现的。我没有RTTI。 (它在HPC环境中,性能齐全!)

getter()应该能够记住这种类型。这样auto可以在以后使用。

2 个答案:

答案 0 :(得分:4)

  

getter()应该能够记住类型。

它不能。您删除了类型。当你将一个任意类型的值放在一致类型的对象中时会发生这种情况。它被称为“类型擦除”:原始类型从包含类中删除

其中一个后果是该类型无法神奇地恢复。您不能在每个实例的基础上使用类型初始化类,然后让其成员函数之一根据特定实例的初始化方式返回不同的类型。

C ++是一种静态类型语言。必须在编译时定义每个函数的返回类型。由于您在运行时将其放入类中,因此无法更改。

  

它无法记住类型。

     

我无法使用RTTI。

然后你想要的是void*。 RTTI是以类型安全的方式恢复原始值类型的唯一方法。如果您不想要类型安全,那么您需要void*。您要做的就是在static_cast<T*>周围编写一个包装器。

void*static_cast周围编写包装器毫无意义。如果这就是你想要的,并且你愿意接受使用它们的危险(即:破坏类型系统),那么就使用它。 boost::any存在的原因是提供一个类型安全 void*,这样至少你知道什么时候你错误地投了它。

答案 1 :(得分:3)

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]);