我如何理解 std::make_shared 的工作原理?
How do I understand how std::make_shared works?
我遇到了一条将二进制文件读入向量的优雅行,就像这样(有效):
std::ifstream ifs("myfile.bin", std::ios::binary);
std::vector<char> buffer(std::istreambuf_iterator<char>(ifs), {});
相反,因为我希望我的向量成为共享指针,所以我写:
std::ifstream ifs("myfile.bin", std::ios::binary);
auto sp = std::make_shared<std::vector<char>>(std::istreambuf_iterator<char>(ifs), {});
我只是将向量构造函数参数传递给 make_shared(就像我通常创建任何对象的任何共享指针一样)。
但我得到:错误:没有匹配函数来调用 'make_shared'?
详细输出:
/usr/include/c++/11.1.0/bits/shared_ptr.h|873 第 5 栏|注意:候选模板被忽略:替换失败 [with _Tp = std::vector]: 推导出不完整包 , (无值)> 对于模板参数 '_Args'
|| make_shared(_Args&&... __args)
这会起作用:
std::ifstream ifs("myfile.bin", std::ios::binary);
auto sp = std::make_shared<std::vector<char>>(std::istreambuf_iterator<char>(ifs),
std::istreambuf_iterator<char>{});
这是因为您正在使用这个可变参数模板:
template<class T, class... Args>
shared_ptr<T> make_shared( Args&&... args );
其中每个参数类型必须是可推导的,如果不是手动实例化的话。 “{}”不允许参数推导,因此编译器错误。遗憾的是,您还可以显式实例化模板:
auto sp = std::make_shared<std::vector<char>, std::istreambuf_iterator<char>,
std::istreambuf_iterator<char>>({ifs}, {});
在这两种情况下,迭代器的类型别名可能会提高可读性(using InputIt = std::istreambuf_iterator<char>;
或类似的东西)。
我遇到了一条将二进制文件读入向量的优雅行,就像这样(有效):
std::ifstream ifs("myfile.bin", std::ios::binary);
std::vector<char> buffer(std::istreambuf_iterator<char>(ifs), {});
相反,因为我希望我的向量成为共享指针,所以我写:
std::ifstream ifs("myfile.bin", std::ios::binary);
auto sp = std::make_shared<std::vector<char>>(std::istreambuf_iterator<char>(ifs), {});
我只是将向量构造函数参数传递给 make_shared(就像我通常创建任何对象的任何共享指针一样)。 但我得到:错误:没有匹配函数来调用 'make_shared'?
详细输出:
/usr/include/c++/11.1.0/bits/shared_ptr.h|873 第 5 栏|注意:候选模板被忽略:替换失败 [with _Tp = std::vector
这会起作用:
std::ifstream ifs("myfile.bin", std::ios::binary);
auto sp = std::make_shared<std::vector<char>>(std::istreambuf_iterator<char>(ifs),
std::istreambuf_iterator<char>{});
这是因为您正在使用这个可变参数模板:
template<class T, class... Args>
shared_ptr<T> make_shared( Args&&... args );
其中每个参数类型必须是可推导的,如果不是手动实例化的话。 “{}”不允许参数推导,因此编译器错误。遗憾的是,您还可以显式实例化模板:
auto sp = std::make_shared<std::vector<char>, std::istreambuf_iterator<char>,
std::istreambuf_iterator<char>>({ifs}, {});
在这两种情况下,迭代器的类型别名可能会提高可读性(using InputIt = std::istreambuf_iterator<char>;
或类似的东西)。