在 std::vector 中模板化存储多种不同类型

2023-11-30

谢谢大家抽出宝贵的时间,我真的很感激。

需要使用模板化方式在 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 等外部库。


向量应该是:

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 构造函数和 Var 属性更改为公共...访问它需要 AddData 和 GetData。

不确定在您的示例中您是否在 _NetVar 上有一些虚拟方法(在这种情况下静态指针转换下面可能是一个动态指针转换)

与此相关,您可能想要验证 NetVar 的析构函数(而不仅仅是 _NetDev 的析构函数)正在被调用(在 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与新对象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;
}

这里,向量的内容是std::shared_ptr<_NetVar>这就是我们得到的。该shared_ptr需要向上转换为正确类型的shared_ptr

现在有一个问题,您必须知道向上转换到的正确类型,否则是未定义的行为。如果你有虚拟方法,你可以使用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;
}

最后测试并打印结果。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 std::vector 中模板化存储多种不同类型 的相关文章

随机推荐

  • 如何使用 openxml 在 Excel 文件单元格中的文本上应用字体和颜色

    我是 Openxml 新手 我正在尝试使用 openxml 创建 xlsx 文件 我想对Excel文件中不同单元格的文本应用不同的字体和颜色 我使用它来创建 xlsx 文件 但无法执行字体和颜色部分 SpreadsheetDocument
  • Python 3.6 urllib 为什么行以 b 开头

    我正在使用 python 3 并且不明白为什么输出在每个行的开头都有 b 我不认为 python 2 是这种情况 为什么会这样以及如何删除它 谢谢 import urllib fhand urllib urlopen http www py
  • AngularJS 通过选择空选项进行过滤

    我正在尝试为 AngularJS 中的表构建一个过滤系统 我有一个产品列表 每个产品都与一个系统绑定 我希望能够在选择中列出所有系统 并按所选系统过滤产品 除了选择空选择选项 该选项会过滤掉所有系统 之外 这非常有效 这是我的示例代码 控制
  • PyCharm 奇怪的类型警告[重复]

    这个问题在这里已经有答案了 为什么下面的代码会这样 v None for in range 3 v 1 0 lt lt lt 告诉我这个 意外类型 整数 整数 可能的类型 整数 无 切片 可迭代 无 消除此类警告的一个简单解决方法是添加类型
  • 在 MATLAB 中使用 sendmail 指定抄送地址

    MATLAB 的典型使用 调用sendmail函数看起来像这样 content body text attachments attachment pdf set preferences setpref Internet SMTP Serve
  • 如何检索实际的 OleDb 表架构(不包括其他表列)

    当我运行此代码时 它还会检索表中不存在的一些其他字段 我怎样才能克服这个问题 Dim conn As New OleDb OleDbConnection Create a connection string for an Access da
  • 从 C 到 Objective-C 的回调方法

    我有一个 Objective C 课程 我正在做的是在 Objective C 类中调用 C 函数 这个 C 函数是我在一个文件中实现的 该文件是这个示例 ios 项目的一部分 所有 C 函数都工作正常 到目前为止没有任何问题 当我尝试调用
  • 通过 PHP 使用 maxlength 标签检查表单输入长度

    我的问题很简单 如果我在 HTML 表单中有一些带有 maxlength 标记的输入字段 我也必须通过 PHP 检查输入长度吗 您应该这样做 因为任何人都可以 复制 您的表格并使用它 服务器端检查比客户端更好 它是安全的 例如 您的表格
  • 如何让动画和手势识别器协同工作? (迅速)

    我做了一个简单的项目 带有滑动手势识别器和动画 我让标签移动并且每 3 秒增加一次数字 每次滑动我都需要减少数量 我的手势识别器对象与标签绑定在一起 即它仅在标签范围内工作 当 prog 在没有动画的情况下工作时 一切正常 但是当它有动画时
  • 这个函数签名在sml中是什么意思?

    我正在查看我的教授关于 SML 语言的一些注释 其中一个函数如下所示 fun max gt let fun lp curr curr lp curr a l if gt a curr then lp a l else lp curr l i
  • 返回并使用带有匹配的泛型类型

    我正在开发一个简单的 Rust 应用程序 它接受标准输入并根据它进行操作 我想让每个命令返回一个结果向量 不同的命令可能返回不同类型的向量 这list方法返回一个向量PathBufs 但默认匹配臂返回字符串 use std io fs us
  • 无法在 Apache Tomcat 上运行 JAX-WS Java Web 服务

    Summary 我的任务是编写一个 Java Web 服务来集成企业环境中的两个不同的系统 由于我实际上是一名经验丰富的 C NET MVC 开发人员 并且只认为自己在 Java 方面处于中级水平 因此我首先搜索 Java Web Serv
  • DllImport 非托管、非 .NET Dll 到表示 Char * 和 Void __StdCall 的 .NET 项目

    我有一个用 Borland C 编写的非 net 和非托管 DLL 需要导入 它返回 void 并在函数上具有标识符 stdcall 它还需要传递 char 当我尝试将其添加为 VS 2005 中项目的引用时 它返回无效程序集的错误 我怎样
  • JTabbedPane 中的选项卡不反映按下按钮时的更改

    在我的 GUI 的选项卡中 用户可以编辑员工的姓名 该名称还用作选项卡的标签 因此当确认更改时 应更新选项卡以反映此更改 并将新数据写入数据文件 员工被存储在HashMap在课堂里Employees 这些选项卡是通过迭代来填充的ArrayL
  • 简单 lambda 表达式代码上的“AssignmentOperator Expression”错误

    我现在正在学习如何使用 lambda 表达式 并且我已经看过一些带有简单示例的教程 int x gt x 5 但我的编译器显示此错误 Syntax error insert AssignmentOperator Expression to
  • 任务执行失败:app:processDebugManifest Android Studio 2.3.3

    添加后出现编译错误CardView and 回收视图依赖关系 我检查了每一篇文章 但似乎没有人解决这个问题 Error 错误 任务 app processDebugManifest 执行失败 清单合并失败 属性元数据 android sup
  • 如何将值从主窗体返回到不同的窗体或类(C#)

    由于某些未知的原因 这个愚蠢的事情无法实施 我有一个int count在我想返回到另一个类或表单的主表单中 namespace my speller public partial class login Form public login
  • 如何在 EF 代码优先中禁用链接表的级联删除?

    我想禁用实体框架代码优先的链接表的级联删除 例如 如果许多用户拥有许多角色 并且我尝试删除一个角色 我希望阻止该删除unless当前没有与该角色关联的用户 我已经删除了我的级联删除约定OnModelCreating protected ov
  • CSS 边框渲染

    我想知道是否可以指定边框绘制风格 not border style 与CSS 我需要它至少适用于webkit 嗯 我有一个像这样的元素div border它有四边边框5px silver solid 但取决于班级的增加 比如div bord
  • 在 std::vector 中模板化存储多种不同类型

    谢谢大家抽出宝贵的时间 我真的很感激 需要使用模板化方式在 std vector 中存储不同类型的多个变量 要使用以下函数 程序员必须了解变量存储的顺序以及存储的变量数量 class NetVar 创建一个子类来保存实际变量 templat