【问题标题】:Placing smart pointers in an STL container在 STL 容器中放置智能指针
【发布时间】:2015-05-27 00:01:34
【问题描述】:

我有一个容器,我想用指向 C 类的指针填充它。但是,我宁愿使用 Boost shared_ptr 而不是哑指针。

我将容器声明为container<C*>,但随后出现此错误:

  no known conversion for argument 1 from ‘boost::shared_ptr<C>’ to ‘C* const&’

我应该如何声明容器采用 boost 共享 ptrs?如果可能的话,我也希望它采用愚蠢的指针。


更新:从回复看来,容器确实必须声明为采用智能指针,不能使其同时采用智能或哑指针 .也就是说,没有从聪明到愚蠢或反之的强制。对吗?

【问题讨论】:

  • 你可能真的想要一个 Boost ptr 容器。
  • container&lt;boost::shared_ptr&lt;C&gt;&gt; ... 这就是您要找的东西吗?如果没有,您能否展示一些您正在尝试做的代码。
  • 请创建一个MCVE,没有导致它们的代码的错误消息众所周知是无用的。
  • 似乎是重复。你在发布之前用谷歌搜索过这个吗? stackoverflow.com/questions/4577838/…
  • 因此,共享ptr 和非共享ptr 在构造、复制和销毁方面具有非常不同的行为。确切地说,您希望您的容器对这种智能指针和哑指针的混合做什么?当你访问元素#17(比如)时,你想访问什么类型?复制容器时会发生什么?什么代码决定了哑指针指向的资源的生命周期?你有混合智能指针和哑指针的商业案例吗?为什么要为您的智能指针共享 ptr?这些不是反问句。

标签: c++ boost smart-pointers


【解决方案1】:

这是一个使用 C++11 共享指针的简单工作演示。它们类似于 Boost 共享指针。

#include <iostream>
#include <memory>
#include <vector>

int main( int argc, char* argv[] )
{
    // Create vector
    std::vector<std::shared_ptr<int>> buffer;

    for( int i=0; i<10; i++ )
        buffer.push_back(std::make_shared<int>(i));

    for( int i=0; i<10; i++ )
        if( (*buffer[i]) != i ){
            std::cout << "Match invalid for " << i << "." << std::endl;
            return 1;
        }
    std::cout << "Valid result" << std::endl;

    return 0;
}

我用

编译了这个
g++ main.cpp -o main -std=c++11

【讨论】:

  • 这以什么方式展示了一个包含智能指针和哑指针的向量?
  • 您可以使用std::shared_ptr&lt;T&gt;::get 查询std::shared_ptr 的内部哑指针。否则,您可以创建一个同时具有 shared_ptr 和普通指针的类,以允许您检查其中任何一个。不过,这是一个非常丑陋的解决方案。
  • 是的,但是 OP 要求一种在容器中存储哑指针的方法。将哑指针存储在智能指针中是可行的(即使在 std::shared_ptr&lt;T&gt; 的情况下不让它表现得智能!),但上面并没有证明它的发生。
【解决方案2】:

为了使用向量,您需要明确指定它们将持有的对象的类型。在您的情况下,它将是boost::shared_ptr。我也了解您想在该容器中存储哑指针。您可能是指原始指针。如前所述,您的容器主要可以存储一种类型,但是也有例外,例如类型通过继承或另一种机制(例如序列化)相关,当您尝试时需要一些显式向下转换使用这些对象或类型是泛型类型。尽管如此。这是另一种方法。您不需要同时存储智能指针和原始指针的向量,因为您始终可以从智能指针获取原始/哑指针。您最好的方法是创建这样的向量

std::vector<boost::shared_ptr<foo>> vec;

上面创建了一个向量来存储指向 foo 的共享指针。

那么当你有一个这样的共享指针时

 boost::shared_ptr<foo> foo_ptr(new foo());

你可以这样做

vec.push_back(foo_ptr)

当你需要哑指针时,你可以这样做

foo* f = vec[0].get();

我阅读了你所说的更新

... 看来容器确实必须声明为 smart 指针,不能采用智能指针或哑指针。

你应该明白boost::shared_ptr&lt;Type&gt;是一个智能指针。

【讨论】:

  • 否:OP 的要求是可能的。我可以用不止一种方式来写它。问题是,OP 希望以什么方式完成,而不是“这是不可能的”。
  • 据我了解,OP 希望在std::vector 中包含这两种类型。我不确定 std::vector 如何包含多个不相关的类型。
  • 很多方法:unionstd::aligned_storagevoid*&type_id*在较低级别,std::experimental::anyboost::variant,在较高级别自定义类型擦除?我的问题是你说“你不能这样做”。也许他们不应该这样做。可能你不知道该怎么做。但是当你在 C++ 中说“这不能做”时要小心:知道什么不能做有时需要知道所有可以做的事情!
  • OP 要求在容器中存储哑指针。有趣的是,通过将 noop 删除器放入 std::shared_ptr,您可以让它存储一个哑指针。不确定这是否是个好主意。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-04
  • 2022-01-23
  • 2011-06-14
  • 2019-07-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多