在没有模板参数的情况下提升make_shared
boost make_shared without template argument
我正在尝试将指向堆栈变量的指针传递给一个只需要boost::shared_ptr
的函数(我不控制)。
根据这个答案,使用boost::make_shared
是要走的路。为了测试这个功能,我写了这个:
#include <iostream>
#include <boost/shared_ptr.hpp>
#include <boost/make_shared.hpp>
int main(int argc, char const *argv[])
{
int i = 10;
boost::shared_ptr<int> int_ptr = boost::make_shared(i); // doesn't work
some_function(int_ptr); // this function takes only shared_ptr
return 0;
}
但它会引发以下错误:
error: no matching function for call to ‘make_shared(int&)’
boost::shared_ptr<int> int_ptr = boost::make_shared(i);
^
如果我像这样添加模板参数,它可以工作,但这是什么原因?
boost::shared_ptr<int> int_ptr = boost::make_shared<int>(i);
谢谢!
给定boost::make_shared<T>
模板:
namespace boost {
template<typename T, typename Arg1>
shared_ptr<T> make_shared( Arg1 const & arg1 );
}
模板机制可以推导出参数arg1
的类型。因为它"看到"了i
参数的类型(即int
)。但是,它无法推断返回类型T
。它不知道您将分配到的boost::shared_ptr<T>
的类型T
(即它无法知道int_ptr
的类型。
boost::shared_ptr<T>
对参数(Arg1
)和返回(T
)使用不同的类型,以允许您从不同于指针类型的参数构建共享指针。例如,double
int
:
double d = 10.0;
std::shared_ptr<int> int_ptr = std::make_shared<int>(d);
如果要构建类型与参数相同的共享指针,可以编写一个包装器:
template<typename T>
boost::shared_ptr<T> my_make_shared(T const & arg) {
return boost::make_shared<T>(arg);
}
但请记住,虽然这有效:
int i = 10.0;
std::shared_ptr<int> int_ptr = my_make_shared(i); // OK
隐式类型转换不会:
double d = 10.0;
std::shared_ptr<int> int_ptr = my_make_shared(d); // ERROR
希望对您有所帮助!
虽然Guilherme Ferreira的回答详细阐述了模板参数推导(在这方面是正确的),但我相信这不是你要找的答案。
我正在尝试将指向堆栈变量的指针传递给一个只需要 boost::shared_ptr 的函数(我不控制)。
shared_ptr
表示对指向对象的共享所有权。如果您尝试调用的函数将指针保存在其某些数据结构(如容器)中,然后返回,则一旦堆栈上的值被销毁,指针就会变得悬空,尽管shared_ptr
仍然持有引用。为了执行所需的操作,您必须绝对确定该函数不会将指针保存在任何地方,并且只能在这一次调用期间使用它。
如果满足此条件,您可以创建一个指向堆栈上值的shared_ptr
,但不能为此使用make_shared
。make_shared
堆上分配一个新对象及其引用计数器,并使用传递给函数调用的参数对其进行初始化。返回的shared_ptr
指向该新对象,而不是堆栈上的对象。
void foo()
{
int n = 10;
boost::shared_ptr< int > pn = boost::make_shared< int >(n);
assert(*pn == 10); // succeeds
assert(pn.get() == &n); // fails
bar(pn);
}
这意味着bar
对尖头int
所做的修改不会反映在n
上。
为了创建对现有对象的shared_ptr
,您必须直接使用其构造函数。此外,由于对象的生存期由堆栈控制,因此您必须禁止shared_ptr
销毁对象。这可以通过在构造shared_ptr
上指定无操作删除器来完成。
void foo()
{
int n = 10;
boost::shared_ptr< int > pn(&n, boost::null_deleter());
assert(*pn == 10); // succeeds
assert(pn.get() == &n); // succeeds
bar(pn);
}
但请注意,此代码仍shared_ptr
使用的引用计数器分配堆内存,因此您不会赢得任何性能。
- VS Code "command":"make"与终端窗口中的命令行"make"不同
- 使用 make 编译 MPI,几个命名空间错误,例如"错误:未知类型名称'使用'?
- make 命令如何避免重新编译未更改的源文件?
- MAKE:找不到包含的用户定义的头文件?
- 'make check' GLIBC 运行时的链接问题
- 引用 std::shared:ptr 以避免引用计数
- Qt5 [make -snap] 无法正确编译:进程"/usr/bin/snap"代码 1 退出
- mingw32-make 使用"MinGW Makefiles"生成器跟踪 CMAKE 无法将可执行文件链接到对象库
- make 命令创建 .file,但不创建应用程序文件
- 如何摆脱导入的 make 项目中的 Eclipse 索引器"Type std::... could not be resolved"错误
- Qt Creator 在执行步骤 "make" 时出现编译错误,-fno-stack-limit
- 如何使用MySQL Connector and Make设置C++项目
- 使用 make 将对象文件放在特定目录中
- 我是 C++ 的新手,我试图调用 make 一个以 2 个类作为其参数的类构造函数
- "Make"失败并出现 Clang 错误 - 如何从 Clang 获得错误?
- dopen():不以 root 身份运行时"failed to map segment from shared object"
- 防止 GNU Make 在每次构建时生成 protobuf 代码
- Make zmqpp::socket::connect a std::future
- 链接从命令行转换为Make的库
- 将 make 和 cmake 合并到构建系统中