std::shared_ptr 和初始化列表

新手上路,请多包涵

std::shared_ptr 构造函数的行为不像我预期的那样:

 #include <iostream>
#include <vector>

void func(std::vector<std::string> strings)
{
    for (auto const& string : strings)
    {
        std::cout << string << '\n';
    }
}

struct Func
{
    Func(std::vector<std::string> strings)
    {
        for (auto& string : strings)
        {
            std::cout << string << '\n';
        }
    }
};

int main(int argc, const char * argv[])
{

    func({"foo", "bar", "baz"});
    Func({"foo", "bar", "baz"});
    //auto ptr = std::make_shared<Func>({"foo", "bar", "baz"}); // won't compile.
    //auto ptr = std::make_shared<Func>{"foo", "bar", "baz"}; // nor this.
    return 0;
}

我做错了什么还是编译器?编译器是:

$ clang++ –version Apple clang 版本 4.0 (tags/Apple/clang-421.0.57) (基于 LLVM 3.1svn)

编辑:shared_ptr 而不是 make_shared。

这是错误:

 make -k
clang++ -std=c++11 -stdlib=libc++    main.cc   -o main
main.cc:28:18: error: no matching function for call to 'make_shared'
      auto ptr = std::make_shared<Func>({"foo", "bar", "baz"});
                 ^~~~~~~~~~~~~~~~~~~~~~
/usr/bin/../lib/c++/v1/memory:4621:1: note: candidate function not viable:
     requires 0 arguments, but 1 was provided
make_shared(_Args&& ...__args)
^
1 error generated.

原文由 dpj 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 896
2 个回答

尝试这个:

 auto ptr = std::make_shared<Func>(std::initializer_list<std::string>{"foo", "bar", "baz"});

Clang 不愿意推断 {"foo", "bar", "baz"} 的类型。我目前不确定这是否是该语言应该工作的方式,或者我们是否正在查看编译器错误。

原文由 Howard Hinnant 发布,翻译遵循 CC BY-SA 3.0 许可协议

--- 的构造函数采用 shared_ptr<T> T* 的指针作为其参数,假定指向动态分配的资源(或至少可以被删除器释放的东西)。另一方面, make_shared 为您进行构造并直接获取构造函数参数。

所以要么你这样说:

 std::shared_ptr<Foo> p(new Foo('a', true, Blue));

或者,更好、更有效:

 auto p = std::make_shared<Foo>('a', true, Blue);

后一种形式为您处理分配和构造,并在此过程中创建更有效的实现。

您当然也可以说 make_shared<Foo>(Foo('a', true, Blue)) ,但这只会创建不必要的副本(可能会被省略),更重要的是它会产生不必要的冗余。 [ 编辑]对于初始化你的向量,这可能是最好的方法:

 auto p = std::make_shared<Func>(std::vector<std::string>({"a", "b", "c"}));

不过,重要的一点是 make_shared 为您 _执行动态分配_,而 shared-ptr 构造函数 _不会_,而是 _取得所有权_。

原文由 Kerrek SB 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题