【问题标题】:Create a vector of shared_ptr to ints创建一个 shared_ptr 到整数的向量
【发布时间】:2017-05-25 11:38:35
【问题描述】:

试图创建一个 shared_ptr 到 int 的向量。

我哪里错了?谢谢。基思:^)

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

int main() {
    std::vector<std::shared_ptr<int> > w;
    std::vector<std::shared_ptr<int> >::iterator it_w;
    w.push_back(new int(7));

    std::cout << std::endl;
}

编译结果:

pickledegg> g++ -std=c++11 -o shared_ptr shared_ptr.cpp
shared_ptr.cpp:29:4: error: no matching member function for call to 'push_back'
        w.push_back(new int(7));
        ~~^~~~~~~~~
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/vector:697:36: note: 
      candidate function not viable: no known conversion from 'int *' to 'const value_type' (aka
      'const std::__1::shared_ptr<int>') for 1st argument
    _LIBCPP_INLINE_VISIBILITY void push_back(const_reference __x);
                                   ^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/vector:699:36: note: 
      candidate function not viable: no known conversion from 'int *' to 'value_type' (aka
      'std::__1::shared_ptr<int>') for 1st argument
    _LIBCPP_INLINE_VISIBILITY void push_back(value_type&& __x);
                                   ^
1 error generated.

【问题讨论】:

    标签: c++ c++11 shared-ptr smart-pointers


    【解决方案1】:

    接受原始指针的std::shared_ptr&lt;T&gt; 构造函数被标记为显式。 source。您将无法使用原始指针调用push_back,因为它不能隐式转换为std::shared_ptr&lt;int&gt;push_back 将其作为参数。解决方案是使用emplace_back 代替push_back 或使用std::make_shared&lt;int&gt;

    emplace_back 匹配给 T 的构造函数之一的参数。

    w.emplace_back(new int(7));
    

    std::make_shared&lt;int&gt; 返回一个std::shared_ptr&lt;int&gt; 类型的对象,避免了这个问题。

    w.push_back(std::make_shared<int>(7));
    

    您可以组合这些解决方案。

    #include <iostream>
    #include <vector>
    #include <memory>
    
    int main(int argc, char** argv) {
        std::vector<std::shared_ptr<int> > w;
        std::vector<std::shared_ptr<int> >::iterator it_w;
        w.emplace_back(std::make_shared<int>(7));
    
        std::cout << std::endl;
    }
    

    编辑:作为附加说明,总是更喜欢std::make_shared&lt;T&gt;(...) 而不是std::shared_ptr&lt;T&gt;(new T(...))。它旨在避免非常微妙的潜在内存泄漏。它还优雅地避免了new 没有delete 的情况,这可能会打扰某些人。

    编辑 2:此外,std::make_shared&lt;T&gt;(...) 具有性能优势,它可以避免在 `std::shared_ptr(new T(...))' see this answer 中进行额外分配。

    【讨论】:

    • “它还优雅地避免了new 没有delete 的情况,这可能会困扰某些人”我发现现在它往往比人们更频繁地打扰静态代码分析工具。
    • emplace_back(std::make_shared&lt;int&gt;(7)) 调用 std::shared_ptr 的 copy-ctor,这有点笨拙,因为 emplace_back 可以解决这个问题。
    • “make_shared”和“emplace_back”都需要吗? w.push_back(std::make_shared&lt;int&gt;(7)); 可以接受吗?
    • 编辑 3:非常微妙:使用 make_shared 的缺点是,只要任何弱指针还活着,用于实际对象的内存就不会被回收。但这真的很重要。
    • @kmiklas 我相信这两种形式在这种情况下是等价的。还有其他关于 SO 的问题可以更彻底地调查这两种方法之间的区别(like this onethis one)。
    猜你喜欢
    • 1970-01-01
    • 2016-08-18
    • 2016-04-18
    • 2018-07-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-04
    相关资源
    最近更新 更多