Когда boost :: bind приводит аргументы к требуемому типу? - PullRequest
2 голосов
/ 12 января 2011

Когда я использую boost :: bind для привязки параметров к функции - когда они приводятся к типу, требуемому функцией (если возможно неявное приведение)?

Как они хранятся в bind_tобъект?Как тип, первоначально переданный для связывания, или как тип, требуемый сигнатурой функции?

В частности:

Если у меня есть функция сигнатуры

void SomeFun(SmartPointer<SomeType>)

ииспользуйте bind как

boost::bind(&SomeFun, somePtr)

, где somePtr имеет тип SomeType*, будет ли объект bind_t содержать копию somePtr, сохраненную как простой указатель, или будет приведен к SmartPointer<SomeType> и хранится как SmartPointer<SomeType>?

Существует неявное приведение от SomeType* до SmartPointer<SomeType>.В отличие от boost::shared_ptr этот SmartPointer использует счетчик ссылок в управляемых объектах, то есть SomeType должен быть получен из SmartPointed.

Ответы [ 2 ]

2 голосов
/ 12 января 2011

Это даже не сработает, так как нет неявного преобразования или неявного конструктора для shared_ptr из SomeType *.

Вы должны позвонить

boost::bind(&SomeFun, boost::shared_ptr<SomeType>(somePtr))

если somePtr - указатель, который вы только что присвоили "new", и ожидаете, что он будет удален позже, когда последняя ссылка shared_ptr выйдет из области видимости. Если вы не хотите, чтобы указатель был удален, но вы знаете, что он все еще будет действителен во время вызова, и функция должна принимать shared_ptr, вы можете использовать no-op delete для создания shared_ptr. В любом случае, это - shared_ptr, а не указатель, слабый_птр или что-то еще, что вы должны передать в этом случае.

Вы говорите, что ваш случай отличается, поэтому нам нужно увидеть ваш фактический случай или тот, который соответствует ему.

Возможно, вас смущает случай, когда передаваемая вами функция является функцией-членом класса, а вы передаете экземпляр класса (объект) в качестве одного из параметров. Здесь вы можете передать указатель, ссылку или shared_ptr, и это может быть константная ссылка, если функция является const-методом (аналогично указателю на const или shared_ptr на const).

Это просто потому, что существуют разные перегрузки для boost :: bind для всех этих случаев, когда функция является функцией-членом класса.

Если преобразование неявное, то неявное преобразование произойдет во время вызова функции. boost :: bind - это просто шаблон, в котором хранится то, что передается в него. Некоторая магия произойдет с первым параметром, если он используется для вызова функции-члена.

Обратите внимание, что иногда boost :: bind будет хранить boost :: ref, где функция на самом деле берет ссылку.

0 голосов
/ 29 июня 2012

Они сохраняются как переданный тип.

Преобразование произойдет, когда вы вызовете объект функции, возвращенный связыванием, а НЕ при выполнении связывания.

Если бы конструктор shared_ptr НЕ был помечен явно в:

template<class Y>
explicit shared_ptr( Y * p ): px( p ), pn( p ) // Y must be complete

тогда бы вы получили интересную ошибку, учитывая это поведение boost :: bind. Если бы вы вызывали функтор только один раз, тогда все было бы хорошо, и ваш объект был бы удален. Если бы вы вызывали его несколько раз, у вас была бы ошибка двойного освобождения и использования после освобождения, так как во второй раз, когда вы создавали shared_ptr из вашего указателя, вы бы использовали указатель, который уже был освобожден.

(я только что задал связанный вопрос о том, почему boost :: bind реализован таким образом)

...