The entry std :: min / std :: max for ints of heterogeneous width

My C ++ program uses unsigned ints of various widths to express restrictions on what data can be represented. For example, I have a file whose size is equal uint64_t, and I want to read it in pieces with a buffer whose size is equal size_t. The chunk is smaller than the buffer size and the (remaining) file size:

uint64_t file_size = ...;
size_t buffer_size = ...;
size_t chunk_size = std::min(buffer_size, file_size);

but this fails because it std::minrequires that both parameters have the same type, so I have to start and then back off:

size_t chunk_size = \
    static_cast<size_t>(std::min(static_cast<uint64_t>)buffer_size, \
                                 file_size));

This casting should not be unnecessary, because it is obvious that min(size_t, uint64_t)it will always match size_t.

How can I write a generic function minthat takes two (possibly different) unsigned types, and whose return type is the smaller of the two types?

+4
source share
1 answer

If you want to explicitly overlay on the smaller, you should just tell the compiler that:

std::min<smaller_type>(buffer_size, file_size)

This is pretty clear and everyone will understand what you are doing. I would just stick with that. You provide the type you want at the dial peer. This is more readable than hiding it behind a function template somewhere every time.

Although, given the potential overflow problems, you can:

template <typename U, typename V>
using smaller_type = std::conditional_t<sizeof(U) < sizeof(V), U, V>;

template <typename U, typename V>
using larger_type = std::conditional_t<sizeof(V) < sizeof(U), U, V>;

template <typename U, typename V>
smaller_type<U, V> my_min(const U& u, const V& v) {
    return std::min<larger_type<U, V>>(u, v);
}
+4
source

All Articles