2010-03-11 5 views
2

Cet exemple simple ne parvient pas à compiler VS2K8:Comment utiliser correctement boost :: make_shared_ptr?

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

Comme le fait celui-ci:

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

L'erreur est:

erreur C2664: « boost :: asio :: basic_deadline_timer :: basic_deadline_timer (boost :: asio :: io_service &, const boost :: posix_time :: ptime &) ': impossible de convertir le paramètre 1 à partir de' const boost :: asio :: io_ service » à 'boost :: asio :: io_service &'

Répondre

7

Le problème est que asio::deadline_timer a un constructeur qui nécessite une référence non-const à un service. Toutefois, lorsque vous utilisez make_shared, son paramètre est const. Autrement dit, cette partie de make_shared est le problème:

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 

    // ... 
} 

Ce que vous pouvez faire est de terminer le service en un reference_wrapper, en utilisant 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)); 

Cela prend votre exemple, et la met en un objet qui peut être implicitement converti en une référence à votre isntance. Vous avez ensuite passé un objet représentant une référence non-const à votre instance.

Cela fonctionne parce que le reference_wrapper stocke vraiment un pointeur sur votre instance. Il peut donc retourner ce pointeur déréférencé tout en étant const.

+0

Excellent, merci! Je n'avais aucune idée de boost :: ref. A-t-il été créé en partie pour contourner ce genre de choses ou y a-t-il d'autres utilisations? – ApplePieIsGood

+0

@Apple: Il a été conçu à peu près pour cette raison. Par exemple, 'boost :: thread' fera une copie de ses arguments pour le nouveau thread, mais si vous voulez réellement passer une référence' boost :: ref' fonctionne aussi. Il est utilisé chaque fois que vous voulez passer une référence, mais la fonction a l'intention de faire une copie. – GManNickG

Questions connexes