C++ std::共享的ptr和初始值设定项列表

C++ std::共享的ptr和初始值设定项列表,c++,c++11,clang,shared-ptr,initializer-list,C++,C++11,Clang,Shared Ptr,Initializer List,std::shared_ptr构造函数的行为与我预期的不同: #include <iostream> #include <vector> void func(std::vector<std::string> strings) { for (auto const& string : strings) { std::cout << string << '\n'; } } struct Fu

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;
}
#包括
#包括
void func(标准::向量字符串)
{
用于(自动常量和字符串:字符串)
{

std::cout如果你想创建一个新对象,你需要使用
make_shared
,这个对象由
shared_ptr
指向,由
shared_ptr
构建,它就像是指向
T
的指针-它需要用指向
T
的指针构建,而不是
T


编辑:当涉及初始值设定项列表时,完美转发实际上并不完美(这是最糟糕的)。这不是编译器中的错误。您必须手动创建
Func
类型的右值。

共享\u ptr
的构造函数将
T*
类型的指针作为其参数,假定该指针指向动态分配的资源(或至少是删除程序可以释放的内容).另一方面,
make_shared
为您进行构造,并直接获取构造函数参数

所以你要么说:

std::shared_ptr<Foo> p(new Foo('a', true, Blue));
std::shared_ptr p(新Foo('a',true,Blue));
或者,更好、更有效:

auto p = std::make_shared<Foo>('a', true, Blue);
auto p=std::使_共享('a',true,蓝色);
后一种形式负责为您进行分配和构造,并在此过程中创建更高效的实现

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

auto p = std::make_shared<Func>(std::vector<std::string>({"a", "b", "c"}));
autop=std::make_shared(std::vector({“a”、“b”、“c”}));
不过,重要的一点是,
make_shared
为您执行动态分配,而共享ptr构造函数不执行,而是拥有所有权。

尝试以下方法:

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

Clang不愿意推断
{“foo”、“bar”、“baz”}
的类型。我目前不确定这是该语言的工作方式,还是我们正在研究编译器错误。

对不起,问题在于make_shared。我在futzing时将其更改为shared_ptr。“但这只会创建一个不必要的副本。”一个不必要的移动。@ildjarn:嗯,这要看情况而定,不是吗?无论如何,“移动”只是一个优化的副本:-)最后我听说,当涉及初始值设定项列表时,完美的转发实际上并不是完美的。{“foo”、“bar”、“baz”}不是一个表达式,因此没有类型(与auto一起使用时除外)…虽然
{“foo”,“bar”,“baz”}
可以是
std::string
char[][]]
wchar\u t[][]
的数组,但编译器必须确切地知道它需要创建什么。
auto ptr = std::make_shared<Func>(std::initializer_list<std::string>{"foo", "bar", "baz"});