2017-06-19 4 views
5

std::chrono::durationの1種類を別の種類に変換する必要がありますが、値が表現できないため、そのような変換が不可能な場合はいつ知る必要があります。duration_castのオーバーフローをチェックする方法

これを確認するための標準ライブラリの機能が見つかりませんでした。 cppreference pageは、値が範囲外の場合に何が起こるかを指定しません。浮動小数点から整数への変換は、未定義の動作(私の場合、整数から整数に変換する必要があります)だけです。

答えて

2

にはフリーサイズソリューション、範囲チェックのためにdoubleベースdurationを使用することです多くのユースケースに合うしかし解決策はありません。多分何かのように:私にとって

#include <chrono> 
#include <iostream> 
#include <stdexcept> 

template <class Duration, class Rep, class Period> 
Duration 
checked_convert(std::chrono::duration<Rep, Period> d) 
{ 
    using namespace std::chrono; 
    using S = duration<double, typename Duration::period>; 
    constexpr S m = Duration::min(); 
    constexpr S M = Duration::max(); 
    S s = d; 
    if (s < m || s > M) 
     throw std::overflow_error("checked_convert"); 
    return duration_cast<Duration>(s); 
} 

int 
main() 
{ 
    using namespace std::chrono; 
    std::cout << checked_convert<nanoseconds>(10'000h).count() << "ns\n"; 
    std::cout << checked_convert<nanoseconds>(10'000'000h).count() << "ns\n"; 
} 

この出力:

36000000000000000ns 
libc++abi.dylib: terminating with uncaught exception of type std::overflow_error: checked_convert 
関連する問題