When does boost::bind cast arguments to the required type?
When I use boost::bind to bind parameters to a function - when are they casted to the type required by the function (if an implicit cast is possible)?
How are they stored in the bind_t object? As the type originally passed to bind or as the type required by the function signature?
Specifically:
If I have a function of the signature
void SomeFun(SmartPointer<SomeType>)
and I use bind as
boost::bind(&SomeFun, somePtr)
where somePtr
is of type SomeType*
, will the bind_t
object contain a copy of somePtr开发者_C百科
stored as a simple pointer or will it be casted to the SmartPointer<SomeType>
and be stored as a SmartPointer<SomeType>
?
There is an implicit cast from SomeType*
to SmartPointer<SomeType>
. As opposed to boost::shared_ptr
this SmartPointer
uses a reference counter in the managed objects, meaning SomeType
has to be derived from SmartPointed
.
This won't even work as there is no implicit conversion or implicit constructor to shared_ptr from SomeType*.
You should call
boost::bind(&SomeFun, boost::shared_ptr<SomeType>(somePtr))
if somePtr is a pointer you have just allocated with "new" and expect to be deleted later when the last reference of the shared_ptr goes out of scope. If you don't want the pointer to be deleted but you know it will still be valid at the time of the call, and the function must take shared_ptr, you can use a no-op deleter to create the shared_ptr. Either way, it is a shared_ptr, not a pointer or a weak_ptr or anything else you must pass in in this instance.
You say your case is different so we would have to see your actual case or one that matches it closer.
You may be getting confused with the case where the function you pass in is a class member function and you pass in the class instance (the object) as one of the parameters. Here you can pass in a pointer, a reference or a shared_ptr and it can be a const reference if the function is a const-method (similarly pointer-to-const or shared_ptr to const).
That is simply because there are different overloads to boost::bind for all these when the function is a class member function.
Where the conversion is implicit the implicit conversion will happen at the time the function is called. boost::bind is just a template that stored what is passed into it. Some magic will occur with the first parameter if it is used to call a member function.
Note that sometimes boost::bind will store a boost::ref where the function actually takes a reference.
They are stored as the type passed in.
The conversion will happen when you call the function object returned by bind, NOT when you perform the bind.
Had the shared_ptr constructor NOT been marked explicit in:
template<class Y>
explicit shared_ptr( Y * p ): px( p ), pn( p ) // Y must be complete
then you would have ended up with an interesting bug given this behavior of boost::bind. If you had called the functor only once then everything would be fine and your object would be deleted. If you had called it multiple times then you would have had a double free and use-after-free bug, since the second time you constructed a shared_ptr from your pointer you would be using a pointer which has already been freed.
(I just asked a related question about why boost::bind is implemented this way)
精彩评论