My C++ program uses unsigned ints of different widths to express constraints on what data can be represented. For example, I have a file whose size is a uint64_t
, and I wish to read it in chunks with a buffer whose size is a size_t
. A chunk is the smaller of 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 std::min
requires that both parameters have the same type, so I must cast up and then back down:
size_t chunk_size = \
static_cast<size_t>(std::min(static_cast<uint64_t>)buffer_size, \
file_size));
This casting ought to be unnecessary, because it is obvious that min(size_t, uint64_t)
will always fit in a size_t
.
How can I write a generic min
function that takes two (possibly different) unsigned types, and whose return type is the smaller of the two types?
If you want to explicitly cast to the smaller one, you should just tell the compiler that:
std::min<smaller_type>(buffer_size, file_size)
That's pretty explicit and everybody will understand what you're doing. I would just stick with that. You're providing the type you want at the point of call. That is more readable than hiding it behind a function template somewhere every time.
Although, given the potential overflow issues, you could do:
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);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With