2013-05-23 16 views
13

Ho un'applicazione che utilizza i timer di scadenza asio. Il resto dell'applicazione usa i costrutti std::chrono per i suoi valori temporali, e ci si sente a disagio nell'usare boost::posix_time solo per le cose che toccano asio. Mi piacerebbe usare std::chrono in tutta l'applicazione, se posso, per coerenza, leggibilità, eccboost :: asio :: deadline_timer con std :: chrono time values ​​

Mi sembra che la risposta comporterebbe utilizzando il modello del timer:

typedef boost::asio::basic_deadline_timer<std::chrono::system_clock::time_point> 
    my_deadline_timer_type; 
my_deadline_timer_type a_timer(io_service); 

Tranne questo fa saltare in aria male al momento della compilazione ... molte linee di errori, molti dei quali sono simili a questo:

/opt/arm/include/boost/asio/deadline_timer_service.hpp:51:43: error: invalid use of incomplete type 'boost::asio::deadline_timer_service > >, boost::asio::time_traits > > > >::traits_type {aka struct boost::asio::time_traits > > >}'

Così, sembra che potrei aver bisogno di creare un nuovo traits_type e dichiarare una deadline_timer_service usarlo, ma io' Non sono sicuro di come/whe ri. Devo credere che questo problema sia stato risolto. Sto usando g ++ 4.7.3 con -std = C++ 11 su linux, cross-compiling per armare.

risposta

24

Se si utilizza spinta 1.49 o successivo, ASIO introdotto il basic_waitable_timer, che utilizza C++ 11 orologi compatibili, sia da std::chrono o boost::chrono. Sono stati inoltre forniti typedef predefiniti per le versioni boost di steady_clock, system_clock e high_resolution_clock. La sua funzionalità è la stessa di deadline_timer, ma utilizza i meccanismi di clock C++ 11 invece delle strutture boost::posix_time.

Per le versioni precedenti, è necessario passare una struttura di tratti per gestire la conversione nel tipo previsto da deadline_timer. Vedere i requisiti ASIO TimeTraits. La maggior parte sono banali, l'ultimo no. Quindi, ad esempio

template<typename Clock> 
struct CXX11Traits 
{ 
    typedef typename Clock::time_point time_type; 
    typedef typename Clock::duration duration_type; 
    static time_type now() 
    { 
     return Clock::now(); 
    } 
    static time_type add(time_type t, duration_type d) 
    { 
     return t + d; 
    } 
    static duration subtract(time_type t1, time_type t2) 
    { 
     return t1-t2; 
    } 
    static bool less_than(time_type t1, time_type t2) 
    { 
     return t1 < t2; 
    } 

    static boost::posix_time::time_duration 
    to_posix_duration(duration_type d1) 
    { 
    using std::chrono::duration_cast; 
    auto in_sec = duration_cast<std::chrono::seconds>(d1); 
    auto in_usec = duration_cast<std::chrono::microseconds>(d1 - in_sec); 
    boost::posix_time::time_duration result = 
     boost::posix_time::seconds(in_sec.count()) + 
     boost::posix_time::microseconds(in_usec.count()); 
    return result; 
    } 
}; 

Si creano quindi timer di scadenza per ciascun orologio C++ 11 che si desidera utilizzare. L'esempio qui è per std::system_clock. Utilizzerai questo timer di scadenza normalmente.

typedef boost::asio::basic_deadline_timer< 
     std::system_clock, 
     CXX11Traits<std::system_clock>> my_system_clock_deadline_timer 
+0

Grazie per la risposta dettagliata, Dave. Il 'basic_waitable_timer' funzionerà bene per me dal momento che sto usando 1.53. Molto obbligato. –