模板化存储多个不同类型在std :: vector中 [英] Templatized Storing Multiple Different Types In std::vector

查看:572
本文介绍了模板化存储多个不同类型在std :: vector中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

谢谢大家的时间我真的很感激它。



存在需要在std :: vector中使用模板化时尚存储不同类型的多个变量。要使用以下函数,程序员必须知道它们存储的变量和存储的变量的顺序。

  class _NetVar {}; 

创建一个子类来保存实际变量:

 模板< class VARTYPE> class NetVar:public _NetVar 
{
private:
VARTYPE Var;
NetVar(VARTYPE值)
{
Var = Value;
}
};

创建一个基本助手类的向量

  std :: vector< _NetVar> DataVec; 

将数据放入向量中,如下所示:

 模板< class DATATYPE> void AddData(DATATYPE AddData)
{
DataVec.push_back(NetVar< DATATYPE>(AddData));
}

这里从数据中提取数据,内部变量保存当前位置并且每次请求变量时递增:

 模板< class DATATYPE> DATATYPE GetData()
{
NetVar< DATATYPE> Temp = PacketData [VecPos];

return Temp.Var;
++ VecPos;
}

上一个函数是出现问题的地方, class



下面是代码的使用方法:

  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':无法从'_NetVar'转换为'NetVar< DATATYPE>'

如果任何人可以帮助我,这将非常感谢,再次感谢你的时间。



注意:外部库

解决方案

向量应为:

  std :: vector< _NetVar *> DataVec; 

或高层指针

  std :: vector< std :: shared_ptr< _NetVar> > DataVec; 

,以便您可以存储子类的实例,而不是将它们切分到基类。








编辑:添加一个完整的工作代码



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<>构造函数和Var属性更改为public ... AddData和GetData需要更多信息,请参考下面的示例:


$ b访问它。



不确定在你的例子中你有一些虚拟方法_NetVar(在这种情况下, static_pointer_cast 下面可以是 std :: make_shared< NetVar< XX>>(...)

  std :: vector< std :: shared_ptr< _NetVar> > DataVec; 
int VecPos;

为以下函数添加了此全局变量。

 模板< class DATATYPE> void AddData(DATATYPE AddData)
{
DataVec.push_back(std :: make_shared< NetVar< DATATYPE>>(AddData));
}

所以这里我们创建一个 shared_ptr 与新对象 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> >(内容)。
++ VecPos;

return Temp-> Var;
}

这里,向量的内容是 std: :shared_ptr< _NetVar> 这就是我们得到的。那个shared_ptr需要被上传到正确的类型shared_ptr



现在有一个担心,你必须知道正确类型upcast,否则是未定义的行为。如果您有虚拟方法,可以使用dynamic_pointer_cast,然后检查null ...但有一些性能惩罚

  int main(){

AddData< int>(32)
AddData< bool>(true);
AddData< std :: string>(Test);

auto Var1 = GetData< int>();
auto Var2 = GetData< bool>();
auto Var3 = GetData< std :: string>();

std :: cout<< Var1<< std :: endl;
std :: cout<< Var2< std :: endl;
std :: cout<< Var3< std :: endl;
return 0;
}

最后测试并打印结果。


thank you all for your time I really appreciate it.

There exists a need to store multiple variables of different types in a std::vector using a templatized fashion. To use the following functions the programmer must be aware of which order they stored the variables and how many variables were stored.

class _NetVar {};

A sub class is created to hold the actual variable:

template <class VARTYPE> class NetVar : public _NetVar
{
private:
    VARTYPE Var;
    NetVar(VARTYPE Value)
    {
        Var = Value;
    }
};

A vector is created of the base helper class

std::vector<_NetVar> DataVec;

Data is put into the vector like so:

template <class DATATYPE> void AddData(DATATYPE AddData)
{
    DataVec.push_back(NetVar<DATATYPE>(AddData));
}

Data is pulled out of the vector here, an internal variable holds the current position of the vector and is incremented each time a variable is requested:

template <class DATATYPE> DATATYPE GetData()
{
    NetVar<DATATYPE> Temp = PacketData[VecPos];

    return Temp.Var;
    ++VecPos;
}

The previous function is where the trouble arises, it is possible to recognize the sub class as it's base class but is it possible to recognize the base class as one of it's sub classes?

Here is how the code is being used:

AddData<int>(32);
AddData<bool>(true);
AddData<std::string>("Test");

auto Var1 = GetData<int>();
auto Var2 = GetData<bool>();
auto Var3 = GetData<std::string>();

When GetData is called an exception is thrown:

'initializing' : cannot convert from '_NetVar' to 'NetVar<DATATYPE>'

If anyone can help me with this it would be greatly appreciated, thank you again for your time.

Note: External libraries such as Boost need to be avoided.

解决方案

The vector should be:

std::vector<_NetVar *> DataVec;

or a high level pointer

std::vector<std::shared_ptr<_NetVar> > DataVec;

so that you can store instances of the child classes instead of slicing them to the base class.

On GetData you will need to upcast the pointer retrieved from the vector.


Edit: Adding a full blown working code

Example working on ideone, had to fiddle with the permissions a bit.

and the example goes with some comments added.

#include <iostream>
#include <vector>
#include <memory>
class _NetVar {};

template <class VARTYPE> 
class NetVar : public _NetVar
{
private:
    VARTYPE Var;
public:
    NetVar(VARTYPE Value)
    {
        Var = Value;
    }
};

Note that I changed NetVar<> constructor and Var attribute to be public... AddData and GetData needed to access it.

Not sure if in your example you had some virtual methods on _NetVar (in which case the static_pointer_cast below could be a dynamic_pointer_cast)

Related to that, you might want to veriy that the destructors for NetVar (and not only the destructors for _NetVar) are being called (checked on ideone, they work in my example because I'm using std::make_shared<NetVar<XX> >(...))

std::vector<std::shared_ptr<_NetVar> > DataVec;
int VecPos;

Added this global variables for the functions below to work.

template <class DATATYPE> void AddData(DATATYPE AddData)
{
    DataVec.push_back(std::make_shared<NetVar<DATATYPE> >(AddData));
}

So here we create a shared_ptr with new object NetVar<DATATYPE> and push it into the vector.

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;
}

Here, the content of the vector is std::shared_ptr<_NetVar> so that's what we get. That shared_ptr needs to be upcasted to the right kind of shared_ptr

Now there's a concern that you must know the right type to upcast to, otherwise is undefined behaviour. If you had virtual methods you could use dynamic_pointer_cast and then perform a check for null... but that has some performance penalties

int main() {

    AddData<int>(32);
    AddData<bool>(true);
    AddData<std::string>("Test");

    auto Var1 = GetData<int>();
    auto Var2 = GetData<bool>();
    auto Var3 = GetData<std::string>();

    std::cout << Var1 << std::endl;
    std::cout << Var2 << std::endl;
    std::cout << Var3 << std::endl;
    return 0;
}

Finally testing and printing the resuls.

这篇关于模板化存储多个不同类型在std :: vector中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆