从基类转换为实例化类模板

时间:2014-07-18 09:40:19

标签: c++

我有几个对象是类模板的实例。我需要将这些对象存储在std::vector中。所以我让类模板继承自基类:

class BaseValue
{
public:
  virtual void Test()
  {
    std::cout << "BaseValue::Test()" << std::endl;
  }
};

template<class T>
class TemplateValue : public BaseValue
{
public:
  TemplateValue(const T &value) : m_value(value)
  {
  }

  virtual void Test()
  {
    std::cout << "TemplateValue::Test() => " << m_value << std::endl;
  }

  T GetValue() const
  {
    return m_value;
  }

  void SetValue(const T &value)
  {
    m_value = value;
  }

private:
  T m_value;
};

基于此,我想做类似的事情:

  TemplateValue<double> *VDouble1 = new TemplateValue<double>(42.42);
  TemplateValue<std::string> *VString2 = new TemplateValue<std::string>("Hi!");
  TemplateValue<double> *VDouble3 = new TemplateValue<double>(0);
  TemplateValue<std::string> *VString4 = new TemplateValue<std::string>("");

  std::vector<BaseValue *> values{VDouble1, VString2, VDouble3, VString4};

  // Error: class BaseValue has no member "SetValue"
  // Error: class BaseValue has no member "GetValue"
  values[2]->SetValue(values[0]->GetValue());
  values[3]->SetValue(values[1]->GetValue());

我怎么能这样做?我在考虑在基类中存储typeId并使用它将BaseValue转换为各自的TemplateValue<T>,然后调用SetValue(const T &value)但不确定这是一个干净的解决方案

备注

  • 我不知道T究竟是什么。有些可能在将来添加,它应该仍然有用。

2 个答案:

答案 0 :(得分:0)

将编译时多态性与运行时多态性混合是不可能的。我会说你不能像现在这样做。

但您可以使用模板类型的特定类型。例如boost::variant,如果您想要提供已知数量的类型。

#include <boost/variant.hpp>

using my_variants = boost::variant<int, std::string>;

class value {
public:

    value(const my_variants &value) : m_value(value) {}


    my_variants set() const {
        return m_value;
    }

    void get(const my_variants &value) {
        m_value = value;
    }

private:
    my_variants m_value;
};

see this running example.

答案 1 :(得分:0)

建立在@ joseph-mansfield建议:

“为什么不让SetValue和GetValue成为BaseValue的虚拟成员?”

我做了什么:

在BaseValue中:

  virtual void SetValue(const BaseValue *bv) = 0;

在TemplateValue中

  void SetValue(const BaseValue *bv)
  {
    auto tv = static_cast<const TemplateValue<T>*>(bv);
    m_value = tv->m_value;
  }

在主要

  values[2]->SetValue(values[0]);
  values[3]->SetValue(values[1]);

唯一的问题是它依赖于static_cast所以如果给定的类型不正确,我就麻烦了。