写std::min/std::max对于异构宽度的int

Writing std::min/std::max for ints of heterogenous widths

本文关键字:std 异构 int 于异构 min max      更新时间:2023-10-16

我的c++程序使用不同宽度的无符号整型来表示可以表示哪些数据的约束。例如,我有一个大小为uint64_t的文件,我希望用一个大小为size_t的缓冲区来读取它。块是缓冲区大小和(剩余的)文件大小中较小的一个:

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

,但这失败了,因为std::min要求两个参数具有相同的类型,所以我必须向上转换,然后向下:

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

这种强制转换应该是不必要的,因为很明显min(size_t, uint64_t)总是适合size_t

我如何写一个通用的min函数,它接受两个(可能不同的)无符号类型,其返回类型是两个类型中较小的?

如果你想显式转换为较小的类型,你应该告诉编译器:

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

这是相当明确的,每个人都会明白你在做什么。我会坚持这样做。您在调用点提供您想要的类型。这比每次都把它隐藏在函数模板后面更容易读懂。

尽管,考虑到潜在的溢出问题,您可以这样做:

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);
}