Вопрос

Этот простой пример не удается скомпилировать в 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 &, постоянный boost::posix_time::ptime &)' :не удается преобразовать параметр 1 из 'const boost::asio::io_service' в 'boost::asio::io_service &'

Это было полезно?

Решение

Проблема в том, что 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.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top