如何在容器中存储不同类型的模板化对象?

2024-03-13

假设我有一个vector (or list或任何可能更适合这里的容器),我想将模板化类型的多个对象(或指针)存储在:

std::vector<MyClass<double>> v;
// std::vector<MyClass<double> *> v;

不幸的是,我想在这个容器中存储不同的模板化对象(并且理想情况下我需要在恒定的时间访问它们)。

我的第一直觉是创造某种WrapperClass around MyClass这将在内部管理任何MyClass作为成员变量,但我不清楚如何将适当的类型传递给MyClass:

#include <iostream>
#include <string>
#include <stdlib.h>
#include <vector>

using namespace std;

template<typename T>
class MyClass
{
public:
    MyClass() {}
    ~MyClass() {}
};

// templating this of course works, but it doesn't solve my problem
template<typename T>
class WrapperClass
{
public:
    WrapperClass()
    {
        m_object = MyClass<T>();
    }

    ~WrapperClass() { }

private:
    MyClass<T> m_object;
};

int main()
{
    WrapperClass<bool> tmp = WrapperClass<bool>();

    std::vector<WrapperClass<bool> *> v;

    return 0;
}

那么有吗(A)与不同的容器vector我可以用它来解决这个问题或者(B)一种选择类型的方法MyClass in WrapperClass在构造函数内部?我在想一些类似的事情:

class WrapperClass2
{
public:
    WrapperClass2(unsigned int typeId)
    {
        switch (typeId)
        {
            case 0: m_object = new MyClass<bool>();
            case 1: m_object = new MyClass<int>();
            case 2: m_object = new MyClass<float>();
            default: m_object = new MyClass<double>();
        }
    }

    ~WrapperClass2()
    {
        delete m_object;
    }

private:
    MyClass * m_object;
};

另一个想法可能是有一些父母AbstractType我将在向量中使用它,但我不确定这将如何帮助解决模板化类型问题。


类模板的不同实例是完全不相关的类型,因此您不能拥有直接存储它们的容器。

您有几个选择:

  1. 保留指向类模板继承自的某个基类的指针集合:
class Base
{
    virtual ~Base {}
    virtual void someMethod() const = 0;
};
    
template <typename T>
class MyClass : public Base
{
    void someMethod() const
    {
        // stuff
    }
};
    
int main()
{
    std::vector<std::unique_ptr<Base>> objs;
    objs.push_back(std::make_unique<MyClass<int>>());
    objs.push_back(std::make_unique<MyClass<std::string>>());

    for (auto& i : objs) {
        i->someMethod();
    }
}

这是一种相当简单的方法,但它会因动态分配和 RTTI 而产生一些运行时开销。另请注意someMethod无法返回T,因为它是父类上的一个方法,不知道它是什么T is.

  1. 使用某种类型擦除的包装器,例如boost::any(或即将推出的std::any在 C++17 中)。
#include <any>
#include <string>
#include <vector>

template <typename T>
class MyClass {
 public:
  T someMethod() const {
    // stuff
    return {};
  }
};

void someFunctionThatTakesInt(int i) {}
void someFunctionThatTakesString(std::string s) {}

int main() {
  std::vector<std::any> objs;
  objs.push_back(MyClass<int>());
  objs.push_back(MyClass<std::string>());

  for (const auto& i : objs) {
    if (i.type() == typeid(MyClass<int>)) {
      auto& mc = std::any_cast<const MyClass<int>&>(i);
      someFunctionThatTakesInt(mc.someMethod());
    } else if (i.type() == typeid(MyClass<std::string>)) {
      auto& mc = std::any_cast<const MyClass<std::string>&>(i);
      someFunctionThatTakesString(mc.someMethod());
    }
  }
}

这种方法意味着您可以someMethod return T,但是使得处理从中检索对象变得更加困难vector因为您必须先弄清楚它们是什么类型,然后才能对它们执行任何操作(您实际上是在滚动自己的 RTTI)。

  1. Don't.

首先重新思考一下为什么你需要这个。也许另一种方法可能效果更好。也许有回调或访客的东西。我不知道你的目的,所以我不能说什么是合适的。

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

如何在容器中存储不同类型的模板化对象? 的相关文章

随机推荐

  • 数组放置新需要缓冲区中未指定的开销?

    5 3 4 expr new C 11 Feb 草案给出了示例 new 2 f T 5 结果调用operator new sizeof T 5 y 2 f 这里 x和y是非负未指定值 表示数组分配开销 的结果新表达将从返回的值中抵消此金额o
  • Flash、Flex、Adobe Air、Java FX 和 Silverlight 到底有什么用?

    Flash Flex Adobe Air Java FX 和 Silverlight 到底有什么用 为什么我会选择其中之一而不是另一个 Java Applet 和 ActiveX 控件发生了什么 哦 AJAX 在哪里适合这一切呢 拉斯洛相关
  • pylint 找不到 QWidget 和 QApplication

    import sys from PyQt5 QtWidgets import QApplication QWidget app QApplication sys argv window QWidget window setGeometry
  • 2D char Array 和 char** 之间的区别(OR、3D char Array 和 char*** 等)

    首先 我已经回顾过这些 多维数组在内存中是如何格式化的 https stackoverflow com questions 2565039 how are multi dimensional arrays formatted in memo
  • Phonegap 屏幕因 AdMob 动画而闪烁

    一位用户报告说 当 admob 广告有动画时 应用程序的 html 视图会 闪烁 这是他录制的一个小视频 http www youtube com watch v gQ7yxzpqfDA http www youtube com watch
  • 从同一类中的另一个构造函数调用构造函数

    我有一个有 2 个构造函数的类 public class Lens public Lens string parameter1 blabla public Lens string parameter1 string parameter2 w
  • 为什么Django的Meta是一个旧式类?

    我注意到在 Django 模型中 有一个class Meta这对模型做了一些额外的定义 我的问题是 为什么这是一个老式的课程 即不子类化object 这是有原因的还是这只是一种习俗 我可以在我的项目中将其作为新式课程吗 我相信没有真正的原因
  • UITableView 延迟图像加载,图像在表格停止滚动后出现

    我使用 NSUrlConnection 为 UITableView 实现了延迟图像加载 这一切都运行得非常好 当我打开桌子时 等待一秒钟 在 3G 上 我会自动获取图像 但是 当我滚动时 表格会加载新单元格 启动 NSURLConnecti
  • Neo4j - 按相关性排序

    我想按 Neo4j 中的相关性对返回的数据进行排序 就我的目的而言 相关性可以简化为 我正在搜索的单词的索引 其中索引越低 相关性越高 Example 我有这三个节点 node Label PROD properties name Bear
  • 使用 java 泛型迭代枚举值

    我试图找到一种在使用泛型时迭代枚举值的方法 不确定如何执行此操作或是否可能 下面的代码说明了我想要做的事情 注意代码T values 在以下代码中无效 public class Filter
  • Javascript:用户完成滚动后执行操作

    我正在想办法做到这一点 我有一个盒子清单 每个盒子都是关于150px高的 我正在使用 javascript 和 jquery 并希望在用户向下滚动页面后 页面将自动滚动 以便框与页面的其余部分对齐 也就是说 如果用户滚动并且 y页面位置不能
  • Spacy - 标记带引号的字符串

    我正在使用 spacy 2 0 并使用带引号的字符串作为输入 示例字符串 The quoted text AA XX should be tokenized 并期望提取 The quoted text AA XX should be tok
  • Aws ecs fargate ResourceInitializationError:无法提取机密或注册表身份验证

    我正在尝试在 aws ecs fargate 1 4 0 平台上运行私有存储库 对于私有存储库身份验证 我遵循了docs https docs aws amazon com AmazonECS latest developerguide p
  • 创建删除线文本?

    我可以在 Android 中创建删除线文本吗 我的意思是在TextView标签可以使这成为可能
  • SQL-Server 中的错误计算

    作为一个例子 我发现了一个简单的计算 例如 select cast 200 00 as float 1908 30 170 00 1150 00 1128 30 作为正常添加 这会导致0 00但 SQL Server 显示结果为2 2737
  • fitz.open() 在 for 循环中不起作用(FITZ、PYTHON、PYMUPDF)

    当我尝试使用 PyMuPDF 中的 fitz 迭代目录 PDFS 中的文件时 我遇到了困难 问题是 当我只是执行 document somepdf pdf 时 代码可以工作 但是一旦我插入 for 循环并尝试访问文件 就会出现此错误 文件名
  • Android 记录来电和去电

    我想了解是否有一种方法可以在 Android 手机 2 2 及更高版本上记录来电和去电 客户希望记录他们给客户拨打的代理电话 以便以后可以用来填写一些材料 他们不想让客户在接听电话时等待 而是希望稍后再做 这可能吗 我需要使用哪些 API
  • 如何配置IntelliJ 11 +远程tomcat 6 + maven导入模块?

    这是我现在所拥有的 将多个maven模块导入到IntelliJ项目中 Maven 目标从 Maven 项目弹出窗口运行正常 创建一个 war 文件 从 Build Make Project 创建项目也可以 但这里没有创建战争 只是创建 cl
  • myBatis 中 ArrayList 的类型处理程序

    我正在尝试为 ArrayList 编写类型处理程序 但这给了我错误任何人都可以帮助我 我想将 ArrayList 作为 VARCHAR 存储在数据库中并将其作为 ArrayList 检索 package com someweb typeha
  • 如何在容器中存储不同类型的模板化对象?

    假设我有一个vector or list或任何可能更适合这里的容器 我想将模板化类型的多个对象 或指针 存储在 std vector