Understanding gsl::narrow implementation

前端 未结 2 1237
青春惊慌失措
青春惊慌失措 2020-12-11 03:55

The C++ Core Guidelines has a narrow cast that throws if the cast changes the value. Looking at the microsoft implementation of the library:

//          


        
2条回答
  •  有刺的猬
    2020-12-11 04:41

    This is checking for overflow. Lets look at

    auto foo = narrow(std::numeric_limits::max())
    

    T will be int and U will be unsigned int. So

    T t = narrow_cast(u);
    

    will give store -1 in t. When you cast that back in

    if (static_cast(t) != u)
    

    the -1 will convert back to std::numeric_limits::max() so the check will pass. This isn't a valid cast though as std::numeric_limits::max() overflows an int and is undefined behavior. So then we move on to

    if (!details::is_same_signedness::value && ((t < T{}) != (u < U{})))
    

    and since the signs aren't the same we evaluate

    (t < T{}) != (u < U{})
    

    which is

    (-1 < 0) != (really_big_number < 0)
    ==  true != false
    ==  true
    

    So we throw an exception. If we go even farther and wrap back around using so that t becomes a positive number then the second check will pass but the first one will fail since t would be positive and that cast back to the source type is still the same positive value which isn't equal to its original value.

提交回复
热议问题