当我使用boost :: bind将参数绑定到函数时 - 它们何时被转换为函数所需的类型(如果可以进行隐式转换)?
它们如何存储在bind_t对象中?最初传递给bind的类型还是函数签名所需的类型?
具体做法是:
如果我有签名功能
void SomeFun(SmartPointer<SomeType>)
我使用bind作为
boost::bind(&SomeFun, somePtr)
其中somePtr
的类型为SomeType*
,bind_t
对象是否包含作为简单指针存储的somePtr
副本,还是会被转换为{{1}并存储为SmartPointer<SomeType>
?
从SmartPointer<SomeType>
到SomeType*
有隐式演员。与SmartPointer<SomeType>
相反,此boost::shared_ptr
在托管对象中使用了引用计数器,这意味着SmartPointer
必须从SomeType
派生。
答案 0 :(得分:2)
这甚至不起作用,因为SomeType *没有对shared_ptr的隐式转换或隐式构造函数。
你应该致电
boost::bind(&SomeFun, boost::shared_ptr<SomeType>(somePtr))
如果somePtr是一个刚刚分配了“new”的指针,并且希望稍后在shared_ptr的最后一个引用超出范围时删除。如果您不希望删除指针,但是您知道它在调用时仍然有效,并且该函数必须使用shared_ptr,则可以使用no-op deleter来创建shared_ptr。无论哪种方式,它都是shared_ptr,而不是指针或weak_ptr,或者在此实例中必须传入的任何其他内容。
你说你的情况不同,所以我们必须看到你的实际案例或者更接近它的案例。
您可能会对传入的函数是类成员函数并将类实例(对象)作为参数之一传入的情况感到困惑。在这里你可以传入一个指针,一个引用或者一个shared_ptr,如果函数是一个const方法(类似指向const或者指向const的共享_ptr),它可以是一个const引用。
这只是因为当函数是类成员函数时,对于所有这些都有不同的boost :: bind重载。
如果转换是隐式的,隐式转换将在调用函数时发生。 boost :: bind只是一个模板,用于存储传递给它的内容。 如果第一个参数用于调用成员函数,则会出现一些魔法。
请注意,有时boost :: bind会存储一个boost :: ref,其中函数实际上是一个引用。
答案 1 :(得分:0)
它们存储为传入的类型。
当您调用bind返回的函数对象时,将发生转换,而不是在执行绑定时发生。
如果shared_ptr构造函数未标记为:
template<class Y>
explicit shared_ptr( Y * p ): px( p ), pn( p ) // Y must be complete
然后,鉴于boost :: bind的这种行为,你最终会遇到一个有趣的错误。如果你只调用了一次仿函数,那么一切都会好的,你的对象就会被删除。如果你多次调用它,那么你就会有一个双重释放和释放后使用的bug,因为你第二次从指针构造一个shared_ptr时你会使用一个已经被释放的指针。
(我刚刚问了related question关于为什么用这种方式实现boost :: bind的方法)