【问题标题】:C++ How can I store multiple types in an vector of shared_ptrs?C++ 如何在 shared_ptrs 的向量中存储多种类型?
【发布时间】:2013-06-21 04:01:17
【问题描述】:

如何在 std::vector 中存储多个 shared_ptr,每个都带有指向不同类型的指针?

std::vector < ? > vec;
vec.push_back( make_shared<int>(3));
vec.push_back( make_shared<float>(3.14f));

是否有一个基本的多态类可以用于该任务而无需使用特定于编译器的东西?

【问题讨论】:

  • 您打算如何以这种方式获取存储类的类型?如果没有共享基类(我习惯于这样做),如果将浮点数和整数混合在一起,您将无法分辨存储的内容。更多关于您要完成的工作的背景知识会有所帮助,因为将这些视为共享指针也让我有些摸不着头脑。
  • 你能解释一下为什么需要这个吗?
  • vector不需要知道类型,它只是一个放置“资源”的地方。我至少需要 1 个 shared_ptr 才能使资源保持活力,因此矢量就在这里。由于有几种类型的资源,我必须使用几种不同的 shared_ptr...顺便说一下,我刚刚通过解决方法解决了这个问题。
  • 只是为了多样化,一个非增强的解决方案是使用可变参数模板,en.wikipedia.org/wiki/Variadic_template,这是 C++11 的一个特性
  • @DarioOO:std::vector 本身并不是为此而设计的。它被设计为T 的容器。因此,您要么需要寻找std::vector 的替代品,要么将您的问题完全减少到T

标签: c++ templates vector shared-ptr polymorphism


【解决方案1】:

有几种方法可以做到这一点。我假设您想存储各种本机类型,因为您使用的是 int 和 float。

  1. 如果您的类型列表是有限的,请使用boost::variant。例如

    std::vector<std::shared_ptr<boost::variant<int, float>>>;
    
  2. 如果您想存储任何内容,请使用boost::any。例如

    std::vector<std::shared_ptr<boost::any>>;
    

【讨论】:

  • 您在模板参数列表的开头而不是末尾留下空格是否有特殊原因?
  • 因为我是格式化帖子的新手。 :-p 它们最初并没有显示为代码块,让编辑器不吞噬我的内部类型的唯一方法是留一个空格。
  • 啊。 :) 说得通。我更正了代码块,但我不想弄乱你惯用的代码风格,即使我发现它很糟糕。 ;-) 很高兴听到我们同意这一点。
【解决方案2】:

我确实需要这样做,请使用boost::any

并使用std::vector &lt;std::shared_ptr&lt;boost::any&gt; &gt; vec;

【讨论】:

    【解决方案3】:

    你不能混合这样的类型。你可能想看看boost::any

    【讨论】:

      【解决方案4】:

      不,C++ 没有像许多其他语言那样派生所有东西的单一类型。 intfloat本机类型,这意味着它们是语言的基础,而不是从其他任何东西派生的。

      如果您受益于 Boost,则可以将 anyvariant 类型存储在您的 vector 中。

      【讨论】:

        【解决方案5】:

        我至少需要 1 个 shared_ptr 才能保持资源活跃

        为此,您存储的所有类型都必须继承自同一个基类,该基类与共享指针中包含的类型相同。此外,基类必须声明一个虚拟析构函数(参见this question)。

        使用boost::any 意味着对象的每个其他shared_ptr 也必须是shared_ptr&lt;bsst::any&gt;,这可能不是您想要的。

        【讨论】:

          【解决方案6】:

          我想解决这个问题的一种可能方法是执行以下操作

          class ISomething{
              bool isAlive;
          public:
              virtual bool alive(){ return isAlive;}
              virtual ~ISomething() {}
          };
          
          template <typename T>
          class Something: public ISomething{
              std::shared_ptr<T> myRes;
          public:    
          };
          
          std::vector<ISomething*> myVec; //push back a new dynamic allocation for each "Something"
          

          这基本上是类型擦除,与 "Boost::Any" "Poco::Any" "Ogre::Any" 背后的概念相同

          【讨论】:

          • 由于称为对象切片的概念,这将不起作用。向量 ONLY 存储对象的 ISomething 部分。尝试存储Something 只会导致Something 的ISomething part 被复制到向量中。当源Something超出范围时,它将被删除,释放shared_ptr上的引用计数。如果您改为堆分配 Something 并存储 std::vector 它会起作用,但这可能不是您想要的。
          • 感谢您的挖掘,是的,基本上我需要“类型擦除”,但这样做的方式不正确。忘了这个答案,我现在改正
          猜你喜欢
          • 2016-01-30
          • 2012-12-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-09-19
          • 2015-12-17
          • 2023-03-31
          • 1970-01-01
          相关资源
          最近更新 更多