在其他模板中使用Any类(类似于boost :: any)

时间:2016-03-22 18:04:58

标签: c++ c++11

我已经实现了一个纯C ++ 11 Any类(基于this code),类似于boost :: any,如果直接使用,效果很好。

但是我现在需要使用它作为模板参数来为变量分配参数。看看这个:

class A {
  IRecognizer<Any, Any> *_recognizer;

  template <typename T1, typename T2>
  A(IRecognizer<T1, T2> *x) : _recognizer(x) {
  }
}

template<typename Symbol, typename ATNInterpreter>
class IRecognizer {
public:

  virtual int getState() = 0;

};

即使我可以将每个模板参数分配给Any变量,我也不允许分配IRecognizer<T1, T2> to IRecognizer<Any, Any>。有这个问题的解决方案吗?错误消息是:

Cannot initialize a member subobject of type 'IRecognizer<Any, Any> *'
with an lvalue of type 'IRecognizer<Token *, ParserATNSimulator *> *'

我使用Any类的原因是有一个可以用任何类引用赋值的公共类型(类似于Java的Object,但是C ++没有所有其他类派生的公共对象类型)。

这里可能采用不同的方法吗?我愿意接受建议。

2 个答案:

答案 0 :(得分:2)

您正在尝试将IRecognizer<T1, T2> *转换为IRecognizer<Any, Any> *。唯一允许的指针转换是从派生类指针到基类指针(即Derived*Base*)或更多 cv - 指向同一类型的指针(即Derived*Derived const*)或两者兼而有之。

IRecognizer<T1,T2>IRecognizer<Any, Any>不在同一个层次结构中。它们是两种不相关的类型。如果有意义的话,您可以添加构造函数将IRecognizer<A,B>转换为IRecognizer<C,D>,但是您无法为指针添加类似的东西。

答案 1 :(得分:1)

指向X的指针与X不同。

虽然您可以将X转换为Y(IRecognizer<T1,T2>转换为IRecognizer<Any,Any>),但您无法将指向X的指针转换为指向Y的指针。< / p>

你可能不想要指针。相反,您可能需要一个值。

但是,界面不是值。

Java泛型与C ++模板不同。 Java通用Bob<Type>Bob<Object>的包装器 - 它实际上存储了一个Object,在它上面的一层中包含了一堆包装转换。 / p>

你可以用C ++编写这样的包装器。举个例子:

class IRecognizer_base {
public:
  virtual int getState() = 0;
};
template<typename Symbol, typename ATNInterpreter>
class IRecognizer:public IRecognizer_base {
};

现在,假设getState()返回了Symbol

class IRecognizer_base {
public:
  virtual Any getState_() = 0;
};
template<typename Symbol, typename ATNInterpreter>
class IRecognizer:public IRecognizer_base {
public:
  inline Symbol getState() {
    return getState_(); // whatever conversion required to go from `Any` to `Symbol`
  }
};

在这里,我们揭露了我们的对象实际上返回Any的事实,但是在接口中我们将它们转换过来。

如果您实际根据模板类型公开了实际上不同的操作,则可以键入擦除策略,以便存储可以执行这些操作的任何操作,而不是指向特定类型的指针。