检查无符号整数的无索引的最佳实践

时间:2015-11-30 11:19:11

标签: c++ unsigned-integer

说我有这个功能:

void doThings(uint8_t index) {
   if (an index is given) { ... }
}

通常,无效索引为-1,因此if语句为if (index != -1)。如果我使用无符号整数来表示索引怎么办?将函数定义更改为signed int是否愚蠢,只是为了测试-1?是否有一个普遍接受的数字代表无符号整数的“无索引”?

5 个答案:

答案 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)作为信号值来表示“无效索引”。

相关问题