当我使用 boost::bind 将参数绑定到函数时 - 它们何时被转换为函数所需的类型(如果可以隐式转换)?
它们如何存储在bind_t对象中?作为最初传递给绑定的类型还是作为函数签名所需的类型?
具体来说:
如果我有一个签名函数
void SomeFun(SmartPointer<SomeType>)
,并且我使用绑定,
boost::bind(&SomeFun, somePtr)
其中 somePtr
的类型为 SomeType*
,那么 bind_t
对象是否包含一个somePtr
的副本存储为简单指针,还是将其转换为 SmartPointer
并存储为 SmartPointer
?
存在从 SomeType*
到 SmartPointer
的隐式转换。与 boost::shared_ptr
相反,这个 SmartPointer
在托管对象中使用引用计数器,这意味着 SomeType
必须从 SmartPointed 派生
。
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
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
.
发布评论
评论(2)
这甚至不起作用,因为没有从 SomeType* 到共享指针的隐式转换或隐式构造函数。
则应该调用
如果 somePtr 是刚刚用“new”分配的指针,并且期望稍后在共享指针的最后一个引用超出范围时将其删除, 。如果您不希望删除该指针,但知道它在调用时仍然有效,并且该函数必须采用shared_ptr,则可以使用无操作删除器来创建shared_ptr。无论哪种方式,它都是一个shared_ptr,而不是一个指针或weak_ptr 或您必须在此实例中传递的任何其他内容。
您说您的情况有所不同,因此我们必须查看您的实际情况或更接近的情况。
您可能会对传入的函数是类成员函数并且传入类实例(对象)作为参数之一的情况感到困惑。在这里你可以传入一个指针、一个引用或一个shared_ptr,如果函数是一个const方法,它可以是一个const引用(类似地指向const的指针或指向const的shared_ptr)。
这只是因为当函数是类成员函数时,所有这些都有不同的重载 boost::bind 。
如果转换是隐式的,则隐式转换将在调用函数时发生。 boost::bind 只是一个存储传递给它的内容的模板。
如果第一个参数用于调用成员函数,则会发生一些神奇的事情。
请注意,有时 boost::bind 会在函数实际获取引用的地方存储 boost::ref 。
This won't even work as there is no implicit conversion or implicit constructor to shared_ptr from SomeType*.
You should call
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.
它们存储为传入的类型。
转换将在您调用绑定返回的函数对象时发生,而不是在执行绑定时发生。
如果shared_ptr构造函数没有在:中被显式标记,
那么考虑到boost::bind的这种行为,你最终会遇到一个有趣的错误。如果您只调用函子一次,那么一切都会好起来,您的对象将被删除。如果您多次调用它,那么您将遇到双重释放和释放后使用错误,因为第二次从指针构造shared_ptr时,您将使用已经被释放的指针。
(我只是问了相关问题关于为什么 boost::bind 是这样实现的)
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:
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)