Как вы правильно используете boost::make_shared_ptr?
-
19-09-2019 - |
Вопрос
Этот простой пример не удается скомпилировать в 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
.