Как правильно использовать boost :: make_shared_ptr? - PullRequest
2 голосов
/ 11 марта 2010

Этот простой пример не компилируется в VS2K8:

    io_service io2;
    shared_ptr<asio::deadline_timer> dt(make_shared<asio::deadline_timer>(io2, posix_time::seconds(20)));

Как и этот:

shared_ptr<asio::deadline_timer> dt = make_shared<asio::deadline_timer>(io2);

Ошибка:

ошибка C2664: 'boost :: asio :: basic_deadline_timer :: basic_deadline_timer (boost :: asio :: io_service &, const boost :: posix_time :: ptime &)': невозможно преобразовать параметр 1 из 'const boost :: asio :: io_service' в'boost :: asio :: io_service &'

1 Ответ

7 голосов
/ 11 марта 2010

Проблема в том, что asio::deadline_timer имеет конструктор, который требует неконстантной ссылки на службу. Однако, когда вы используете make_shared, его параметр равен const. То есть эта часть make_shared является проблемой:

template< class T, class A1 > // service is passed by const-reference
boost::shared_ptr< T > make_shared( A1 const & a1 )
{
    // ...

    ::new( pv ) T( a1 ); // but the constructor requires a non-const reference

    // ...
}

Что вы можете сделать, это превратить службу в reference_wrapper, используя ref:

#include <boost/ref.hpp>

asio::io_service io1;
shared_ptr<asio::deadline_timer> dt = // pass a "reference"
    make_shared<asio::deadline_timer>(boost::ref(io1));

Это берет ваш экземпляр и помещает его в объект, который может быть неявно преобразован в ссылку на ваше происхождение. Затем вы по существу передали объект , представляющий неконстантную ссылку на ваш экземпляр.

Это работает, потому что reference_wrapper действительно хранит указатель на ваш экземпляр. Поэтому он может возвратить этот указатель разыменованным, оставаясь при этом const.

...