Boost:: asio:: deadline_timer со значениями std:: chrono time

У меня есть приложение, которое использует таймеры времени asio. Остальная часть приложения использует конструкторы std::chrono для своих значений времени, и неудобно использовать boost::posix_time только для материала, который касается asio. Я хотел бы использовать std::chrono во всем приложении, если могу, для согласованности, удобочитаемости и т.д.

Мне кажется, что ответ будет включать использование шаблона таймера:

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

За исключением того, что это плохо срабатывает во время компиляции... много ошибок, большинство из которых схожи с этим:

/opt/arm/include/boost/asio/deadline_timer_service.hpp:51:43: ошибка: недопустимое использование неполного типа 'boost:: asio:: deadline_timer_service → , boost:: asio:: time_traits → → :: traits_type {aka struct boost:: asio:: time_traits → > }

Итак, похоже, что мне может понадобиться создать новый traits_type и объявить deadline_timer_service, используя его, но я не уверен, как/где. Я должен поверить, что эта проблема решена. Я использую g++ 4.7.3 с -std = С++ 11 в linux, кросс-компиляция в руку.

Ответ 1

Если вы используете boost 1.49 или новее, ASIO представила basic_waitable_timer, который использует С++ 11 совместимые часы, либо от std::chrono или boost::chrono. Они также предоставили предопределенные typedefs для ускоренных версий steady_clock, system_clock и high_resolution_clock. Его функциональность такая же, как и deadline_timer, но использует механизмы синхронизации С++ 11 вместо структур boost::posix_time.

Для более ранних версий вам нужно будет передать структуру признаков, чтобы обрабатывать преобразование в тип, ожидаемый deadline_timer. См. Требования ASIO TimeTraits. Большинство из них тривиально, а последнее - нет. Итак, например

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;
  }
};

Затем вы создавали таймеры для всех часов С++ 11, которые вы хотите использовать. Пример здесь для std::system_clock. Вы использовали бы этот таймер как обычно.

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