我的 C++ 程序使用不同宽度的无符号整数来表达对可以表示哪些数据的约束。例如,我有一个大小为 a 的文件uint64_t,我希望使用大小为 a 的缓冲区分块读取它size_t。块是缓冲区大小和(剩余)文件大小中较小的一个:
uint64_t file_size = ...;
size_t buffer_size = ...;
size_t chunk_size = std::min(buffer_size, file_size);
Run Code Online (Sandbox Code Playgroud)
但这失败了,因为std::min要求两个参数具有相同的类型,所以我必须先上后退:
size_t chunk_size = \
static_cast<size_t>(std::min(static_cast<uint64_t>)buffer_size, \
file_size));
Run Code Online (Sandbox Code Playgroud)
这种转换应该是不必要的,因为很明显,它min(size_t, uint64_t)总是适合size_t.
我如何编写一个通用min函数,它采用两种(可能不同的)无符号类型,并且其返回类型是这两种类型中较小的一种?
如果你想显式地转换为较小的,你应该告诉编译器:
std::min<smaller_type>(buffer_size, file_size)
Run Code Online (Sandbox Code Playgroud)
这是非常明确的,每个人都会明白你在做什么。我会坚持下去。您在通话时提供所需的类型。这比每次都将它隐藏在函数模板后面更易读。
虽然,考虑到潜在的溢出问题,您可以这样做:
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);
}
Run Code Online (Sandbox Code Playgroud)