最終更新日時(UTC):
が更新

履歴 編集

class template
<chrono>

std::common_type(C++11)

namespace std {
  // (1)
  template <class Rep1, class Period1, class Rep2, class Period2>
  struct common_type<chrono::duration<Rep1, Period1>, chrono::duration<Rep2, Period2>> {
    using type = chrono::duration<common_type_t<Rep1, Rep2>, Period/*下記参照*/>;
  };

  // (2)
  template <class Clock, class Duration1, class Duration2>
  struct common_type<chrono::time_point<Clock, Duration1>, chrono::time_point<Clock, Duration2>> {
    using type = chrono::time_point<Clock, common_type_t<Duration1, Duration2>>;
  };
}

概要

  • (1) : 2つのduration間の変換可能な共通の型を取得する。
  • (2) : 2つのtime_point間の変換可能な共通の型を取得する。

共に、<type_traits>で定義されているcommon_typeの特殊化である。

効果

  • (1) : 数値型RepRep1Rep2の共通型(Rep = common_type_t<Rep1, Rep2>)から、周期を表す型PeriodPeriod1Period2の最大公約数から、それぞれ求めて
    それらに対するduration<Rep, Period>特殊化をメンバ型typeとして定義する。

  • (2) : 同じ時計型Clockと、時間間隔型DurationDuration1Duration2の共通型(Duration = common_type_t<Duration1, Duration2>、すなわち(1)で計算)から求めて
    それらに対するtimepoint<Clock, Duration>特殊化をメンバ型typeとして定義する。

(1)において新しい周期型Period<N, D>は、NPeriod1::numPeriod2::numの最大公約数から、DPeriod1::denPeriod2::denの最小公倍数から、それぞれ求めることで構成できる。

備考

common_typedurationおよびtime_pointについて1引数(common_type_t<duration>のような形)で呼び出したとき、1つ目の引数を2つ目の引数として(1)および(2)の特殊化が呼び出される(common_type_t<duration, duration>の呼び出しになる)。

特に、common_type_t<duration<Rep, Period>, duration<Rep, Period>>の呼び出しは、Repの型に変化はないが、新しいPeriodは元のPeriodを約分した形の型になる(例えば、std::ratio<10, 10> -> std::ratio<1, 1>のように変換される)。

#include <iostream>
#include <chrono>

template<class Rep1, class Period1, class Rep2, class Period2>
constexpr auto duraion_plus(const std::chrono::duration<Rep1, Period1>& d1, const std::chrono::duration<Rep2, Period2>& d2)
  -> std::common_type_t<std::chrono::duration<Rep1, Period1>, std::chrono::duration<Rep2, Period2>>
{
  using common_duration = std::common_type_t<std::chrono::duration<Rep1, Period1>, std::chrono::duration<Rep2, Period2>>;

  return common_duration(d1) + common_duration(d2);
}

template<class Clock, class Duration1, class Duration2>
constexpr auto timepoint_plus(const std::chrono::time_point<Clock, Duration1>& p1, const std::chrono::time_point<Clock, Duration2>& p2)
  -> std::common_type_t<std::chrono::time_point<Clock, Duration1>, std::chrono::time_point<Clock, Duration2>>
{
  using common_timepoint = std::common_type_t<std::chrono::time_point<Clock, Duration1>, std::chrono::time_point<Clock, Duration2>>;

  auto duration = duraion_plus(p1.time_since_epoch(), p2.time_since_epoch());
  return common_timepoint(duration);
}

template<typename Duration>
using timepoint_t = std::chrono::time_point<std::chrono::system_clock, Duration>;


int main()
{
  using namespace std::literals;

  //(1)の使用例、異なるduration間での足し算
  std::cout << duraion_plus(1ms, 10s).count() << std::endl;
  std::cout << duraion_plus(1us, 10ms).count() << std::endl;

  timepoint_t<decltype(1ms)> p1{10ms};
  timepoint_t<decltype(1s)> p2{1s};

  //(2)の使用例、異なるdurationを持つtimepoint間で足し算を定義する
  std::cout << timepoint_plus(p1, p2).time_since_epoch().count() << std::endl;
}

出力

10001
10001
1010

バージョン

言語

  • C++11

処理系

関連項目

参照