的std :: shared_ptr的和初始化列表(std::shared_ptr and init

2019-06-26 19:23发布

该的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;
}

我是不是做错了什么或者是编译器? 编译如下:

$铛++ --version苹果铛版本4.0(标签/苹果/铛 - 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.

Answer 1:

试试这个:

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

锵不愿意推断的类型{"foo", "bar", "baz"} 我目前不知道这是否是语言应该工作,或者如果我们看一个编译器错误的方式。



Answer 2:

的构造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 进行动态分配给你,而共享PTR构造没有 ,而是取得所有权



Answer 3:

您需要使用make_shared如果你想创建一个新的对象,从这些参数构建一个指向shared_ptrshared_ptr<T>就像是一个指针,指向T -它需要的指针被构造T ,而不是一个T

编辑:完美转发其实并不完美的,当初始化列表参与(这是吸)。 这不是在编译器中的错误。 你将不得不创建类型的右值Func手动。



文章来源: std::shared_ptr and initializer lists