如何检查duration_cast中的溢出

Amb*_*jak 7 c++ integer-overflow c++-chrono

我需要将一种转换std::chrono::duration为另一种,但我需要知道何时无法进行这种转换,因为该值无法表示.

我没有在标准库中找到任何设施来检查这一点.该cppreference页面没有指定值是否超出范围会发生什么,只能从浮点到整数的转换可能是不确定的行为(在我来说,我需要从整数转换为整数).

How*_*ant 5

没有一刀切的解决方案,但是适合许多用例的解决方案是使用double-basedduration进行范围检查。也许是这样的:

#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";
}
Run Code Online (Sandbox Code Playgroud)

对我来说,这个输出:

36000000000000000ns
libc++abi.dylib: terminating with uncaught exception of type  std::overflow_error: checked_convert
Run Code Online (Sandbox Code Playgroud)