C++ std::共享的ptr和初始值设定项列表
std::shared_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
#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"});