2010-03-11 1 views
2

Этот простой пример не удается скомпилировать в VS2K8:Как вы правильно используете boost :: make_shared_ptr?

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: «повышение :: ASIO :: basic_deadline_timer :: basic_deadline_timer (boost :: asio :: io_service &, const boost :: posix_time :: ptime &) ': невозможно преобразовать параметр 1 из' const boost :: asio :: io_ Сервис»на„повышение :: ASIO :: io_service &“

ответ

7

Проблема заключается в том, что 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)); 

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

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

+0

Отлично, спасибо! Не знал о boost :: ref. Было ли это частично создано для того, чтобы обойти этот тип вещей или использовать его в других целях? – ApplePieIsGood

+0

@ Аппл: По этой причине он был разработан в значительной степени. Например, 'boost :: thread' будет делать копию своих аргументов для нового потока, но если вы хотите действительно передать ссылку' boost :: ref', там тоже работает. Он используется всякий раз, когда вы хотите передать ссылку, но функция предназначена для создания копии. – GManNickG

 Смежные вопросы

  • Нет связанных вопросов^_^