如何检查duration_cast中的溢出
问题描述:
我需要将std::chrono::duration
中的一种转换为另一种类型,但我需要知道何时这种转换不可能,因为该值无法表示。如何检查duration_cast中的溢出
我还没有在标准库中找到任何设施来检查这一点。 cppreference page没有指定如果值超出范围会发生什么,只有从浮点到整数的转换可能是未定义的行为(在我的情况下,我需要从整数转换为整数)。
答
没有一个尺寸适合所有解决方案,但是适合许多用例是使用基于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