说我有这个功能:
void doThings(uint8_t index) {
if (an index is given) { ... }
}
通常,无效索引为-1,因此if语句为if (index != -1)
。如果我使用无符号整数来表示索引怎么办?将函数定义更改为signed int是否愚蠢,只是为了测试-1
?是否有一个普遍接受的数字代表无符号整数的“无索引”?
答案 0 :(得分:3)
简单地重载doThings
,如下所示:
void doThings(uint8_t index) {
// do things for a given index
}
void doThings() {
// do things for no index
}
或者,如果您只是传递函数的结果,请说findElement
使用std::pair
之类的内容:
std::pair<std::uint8_t, bool> findElement(...);
void doThings(std::pair<std::uint8_t, bool>& arg) {
if (arg.second) {
// do things for given element arg.first
并将其命名为:
doThings(findElement(...));
答案 1 :(得分:2)
如果必须考虑同一功能中的两种情况,更好的选择可能只是提供第二个参数。
void doThings(uint8_t index, bool indexGiven) {
if (indexGiven) { ... }
}
但是,使用两个完全不同的函数,一个用于索引时,一个用于索引时,可能会使设计更清晰。
答案 2 :(得分:0)
将函数定义更改为使用有符号整数并不是愚蠢的,因此您可以检查-1。这是一种常见的做法。
但是,如果该函数是其他人使用的定义良好且已记录的API的一部分,那么您可能不希望将该函数更改为使用signed int。相反,我建议使用MAX_INT(或uint8_t为0xFF)作为无效索引的标志。
答案 3 :(得分:0)
我会使用Maybe类型。
// include some optional type, e.g. experimental/optional or boost/optional.hpp
using maybe_index = optional<std::uint8_t>;
void doThings(maybe_index index) {
if (index) { ... }
else { ... }
}
如果我需要能够表示索引加上特殊的无效状态。 GCC在std::optional
中实施了std::experimental
,并提供了Boost版本。
答案 4 :(得分:0)
问问自己哪些值对索引有效。通常,您有一个数组,并且数组的长度定义了有效范围。如果该数组恰好是256个元素长,则使用uint8_t
的每个可能值作为有效索引,这意味着您需要更多来表示“无效索引”。如果数组较小,那么该数组范围之外的任何索引都是无效的,通常会使用最高值(即static_cast<uint8_t>(-1)
或使用<limits>
标题中的函数。)
这里已经有很多方法,例如一个额外的标志,使用optional<uint8_t>
(您应该记住,因为它适用于您有类似要求的任何地方,不仅适用于索引)或使用重载(这可能不是那种方式,因为这需要编译时决定。)
相反,我会使用更大的索引类型。用于表示索引的通常类型是size_t
,它是无符号整数类型,通常具有指针的大小(即,在公共计算机上为32或64位)。如果你切换到那个,你甚至可以解决你在内存中最大的阵列(不是在磁盘上!)。这样,您还可以使用static_cast<size_t>(-1)
作为信号值来表示“无效索引”。