如何检查duration_cast中的溢出

问题描述:

我需要将std::chrono::duration中的一种转换为另一种类型,但我需要知道何时这种转换不可能,因为该值无法表示。如何检查duration_cast中的溢出

我还没有在标准库中找到任何设施来检查这一点。 cppreference page没有指定如果值超出范围会发生什么,只有从浮点到整数的转换可能是未定义的行为(在我的情况下,我需要从整数转换为整数)。

没有一个尺寸适合所有解决方案,但是适合许多用例是使用基于doubleduration范围检查的解决方案。也许是这样的:

#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