I'm trying to pass a pointer to a stack variable to a function (I don't control) that only takes a boost::shared_ptr
.
According to this answer, using boost::make_shared
is the way to go. In order to test out this functionality I wrote this:
#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;
}
But it throws the following error:
error: no matching function for call to ‘make_shared(int&)’
boost::shared_ptr<int> int_ptr = boost::make_shared(i);
^
If I add the template argument like so it works but what is the reason for this?
boost::shared_ptr<int> int_ptr = boost::make_shared<int>(i);
Thank you!
Given the boost::make_shared<T>
template:
namespace boost {
template<typename T, typename Arg1>
shared_ptr<T> make_shared( Arg1 const & arg1 );
}
The template mechanism can deduce the type of parameter arg1
. Because it "sees" the type of the argument i
(which is int
). However, it can't deduce the return type T
. It does not know the type T
of the boost::shared_ptr<T>
you will assign to (i.e. it has no means to know the type of int_ptr
.)
The boost::shared_ptr<T>
uses different types for argument (Arg1
) and return (T
) to allow you to build shared pointers from arguments different from the pointer type. For instance, double
to int
:
double d = 10.0;
std::shared_ptr<int> int_ptr = std::make_shared<int>(d);
If you want to build shared pointers which the type is the same as the argument, you can write a wrapper:
template<typename T>
boost::shared_ptr<T> my_make_shared(T const & arg) {
return boost::make_shared<T>(arg);
}
But bear in mind that while this works:
int i = 10.0;
std::shared_ptr<int> int_ptr = my_make_shared(i); // OK
The implicit type conversion does not:
double d = 10.0;
std::shared_ptr<int> int_ptr = my_make_shared(d); // ERROR
Hope it helps!