我有几个对象是类模板的实例。我需要将这些对象存储在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)
但不确定这是一个干净的解决方案
备注
答案 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;
};
答案 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
所以如果给定的类型不正确,我就麻烦了。