2017-06-19 15 views
5

Tôi cần chuyển đổi một loại std::chrono::duration sang loại khác nhưng tôi cần biết khi nào một chuyển đổi như vậy là không thể bởi vì giá trị sẽ không thể đại diện được.Cách kiểm tra tình trạng tràn trong duration_cast

Tôi chưa tìm thấy bất kỳ cơ sở nào trong thư viện chuẩn để kiểm tra điều này. cppreference page không xác định điều gì sẽ xảy ra nếu giá trị nằm ngoài phạm vi, chỉ chuyển đổi từ dấu phẩy động sang số nguyên có thể là hành vi không xác định (trong trường hợp của tôi, tôi cần phải chuyển đổi từ số nguyên sang số nguyên).

Trả lời

2

Không có giải pháp một kích thước phù hợp với tất cả, tuy nhiên giải pháp phù hợp với nhiều trường hợp sử dụng là sử dụng double dựa trên duration để kiểm tra phạm vi. Có lẽ cái gì đó như:

#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"; 
} 

Đối với tôi kết quả đầu ra này:

36000000000000000ns 
libc++abi.dylib: terminating with uncaught exception of type std::overflow_error: checked_convert 
Các vấn đề liên quan