简体   繁体   中英

Windows MAX/MIN macros as templates

If I were to write the Windows min/max macros as template functions what would be the correct way of doing it?

The min macro is defined as:

#define min(a, b)  (((a) < (b)) ? (a) : (b)) 

I guess one alternative would be to do this:

template <typename T, typename U, typename R = std::common_type_t<T, U>>
constexpr R min(T const& a, U const& b) {
    return std::min(static_cast<R>(a), static_cast<R>(b));
}

Would that be correct and/or have the exact same behavior?

std::min cannot be used since it expects both arguments to be of the same type. http://en.cppreference.com/w/cpp/algorithm/min

Assuming values a and b are arithmetic types, you could do:

#include <type_traits>

template <typename T, typename U>
constexpr auto min(T a, U b) -> typename std::common_type<T, U>::type {
    // This is a lot cleaner in C++14 where we can use std::common_type_t and local
    // variables in a constexpr function. Alternatively, you could just implement
    // this by casting a and b to their common type and calling std::min.
    return static_cast<typename std::common_type<T, U>::type>(a) <
           static_cast<typename std::common_type<T, U>::type>(b) ?
           static_cast<typename std::common_type<T, U>::type>(a) :
           static_cast<typename std::common_type<T, U>::type>(b);
}

Note, however, that using this comes with the drawbacks of hiding the casts, and it is not obvious what the return type is. For example, mixing signed and unsigned arguments might result in bugs if you aren't careful and intentional.

In general, I would recomment just using std::min and casting the types as needed (eg if a is int and b is float, just do std::min(static_cast<float>(a), b) ).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM