谢谢大家的时间,我真的很感激。
需要使用模板化的方式在std :: vector中存储多个不同类型的变量。要使用以下函数,程序员必须知道它们存储变量的顺序以及存储的变量数。
class _NetVar {};
创建一个子类来保存实际变量:
template <class VARTYPE> class NetVar : public _NetVar
{
private:
VARTYPE Var;
NetVar(VARTYPE Value)
{
Var = Value;
}
};
创建了基本辅助类
的向量std::vector<_NetVar> DataVec;
将数据放入矢量中:
template <class DATATYPE> void AddData(DATATYPE AddData)
{
DataVec.push_back(NetVar<DATATYPE>(AddData));
}
这里从数据中提取数据,内部变量保存向量的当前位置,并在每次请求变量时递增:
template <class DATATYPE> DATATYPE GetData()
{
NetVar<DATATYPE> Temp = PacketData[VecPos];
return Temp.Var;
++VecPos;
}
上一个函数是出现问题的地方,可以将子类识别为它的基类,但是可以将基类识别为它的一个子类吗?
以下是代码的使用方式:
AddData<int>(32);
AddData<bool>(true);
AddData<std::string>("Test");
auto Var1 = GetData<int>();
auto Var2 = GetData<bool>();
auto Var3 = GetData<std::string>();
当调用GetData时,抛出异常:
'initializing' : cannot convert from '_NetVar' to 'NetVar<DATATYPE>'
如果有人可以帮助我,我将不胜感激,再次感谢您的时间。
注意:需要避免使用Boost等外部库。
答案 0 :(得分:3)
矢量应该是:
std::vector<_NetVar *> DataVec;
或高级指针
std::vector<std::shared_ptr<_NetVar> > DataVec;
这样您就可以将子类的实例而不是slicing存储到基类中。
在GetData上,您需要向上转换从向量中检索的指针。
处理ideone的示例,必须稍微改变一下权限。
并且该示例附带了一些评论。
#include <iostream>
#include <vector>
#include <memory>
class _NetVar {};
template <class VARTYPE>
class NetVar : public _NetVar
{
private:
VARTYPE Var;
public:
NetVar(VARTYPE Value)
{
Var = Value;
}
};
请注意,我更改了NetVar&lt;&gt;构造函数和Var属性是公共的......访问它需要AddData和GetData。
不确定您的示例中是否在_NetVar上有一些虚拟方法(在这种情况下,下面的static_pointer_cast可能是dynamic_pointer_cast)
与此相关,您可能想要验证NetVar的析构函数(而不仅仅是_NetVar的析构函数)被调用(在ideone上检查,它们在我的示例中工作,因为我使用std::make_shared<NetVar<XX> >(...)
)
std::vector<std::shared_ptr<_NetVar> > DataVec;
int VecPos;
为以下功能添加了此全局变量。
template <class DATATYPE> void AddData(DATATYPE AddData)
{
DataVec.push_back(std::make_shared<NetVar<DATATYPE> >(AddData));
}
所以我们在这里创建一个带有新对象shared_ptr
的{{1}}并将其推送到向量中。
NetVar<DATATYPE>
这里,向量的内容是template <class DATATYPE> DATATYPE GetData()
{
std::shared_ptr<_NetVar> content = DataVec[VecPos];
std::shared_ptr<NetVar<DATATYPE> > Temp = std::static_pointer_cast<NetVar<DATATYPE> >(content);
++VecPos;
return Temp->Var;
}
,这就是我们得到的。 shared_ptr需要升级到正确的shared_ptr
现在有一个问题是你必须知道要向上转换的正确类型,否则是未定义的行为。如果你有虚拟方法,你可以使用dynamic_pointer_cast,然后检查null ...但是有一些performance penalties
std::shared_ptr<_NetVar>
最后测试并打印结果。
答案 1 :(得分:1)
一种解决方案是摆脱_NetVar
并使用Boost.Any,如:
std::vector<boost::any> DataVec;
template<class T>
void AddData(T data)
{ DataVec.emplace_back(std::move(data)); }
template<class T>
T GetData()
{ return boost::any_cast<T>(DataVec[VecPos++]); }
AddData(32);
AddData(true);
AddData(std::string("test"));
auto Var1 = GetData<int>();
auto Var2 = GetData<bool>();
auto Var3 = GetData<std::string>();