减去无符号整数的有符号结果

Signed result of subtracted unsigned integers?

本文关键字:符号 结果 无符号整数      更新时间:2023-10-16

我正在尝试创建一个类似于vector<string>的类和另一个类似于其迭代器的类(纯粹作为c++ Primer中的练习(感兴趣的人可以练习14.28))。迭代器类使用vector<string>::size_type成员(称为curr)来表示vector的索引。我不希望粘贴整个工作,因为它很长,但是在尝试为迭代器定义自己的减法操作符时,我遇到了一定程度的困惑。最终,它应该像减去两个迭代器一样工作,并在必要时产生负值。函数定义如下:

??? operator-(const iterator& lhs, const iterator& rhs){
    return (lhs.curr - rhs.curr);
}

或者,另一个版本的我的困惑;

#include <vector>
#include <string>
#include <iostream>
using namespace std;
int main(){
    vector<string>::size_type x = 5, y = 3;
    ??? z = (y-x); //what should ??? be if I want -2?
    cout << z;
}

(y-x)-2,但当然包装回到4294967294,因为它是一个32位无符号表达式,在将其存储在z中之前。我无法弄清楚如何定义我的返回类型,以便如果rhs (y)在序列中比lhs (x)更进一步,则返回正确的负值(存储在z中)。

我认为vector<string>::difference_type可能会这样做,但我发现size_type代表一个32位无符号整数,而difference_type代表一个32位有符号整数,所以会有一个错误,用有符号整数包装,这是未定义的行为-即使在我的计算机上它产生正确的结果。我可以将static_cast所有内容都设置为long long int并返回long long int,但我觉得这有点太暴力了。

正确的类型确实是vector<string>::difference_type。您可以像这样轻松地实现迭代器减法:

difference_type operator- (const iterator &lhs, const iterator &rhs)
{
  if (rhs.curr >= lhs.curr) return static_cast<difference_type>(rhs - lhs);
  else return - static_cast<difference_type>(lhs - rhs);
}

标准库的实际实现可能并不一定需要这样做,因为它们通常针对特定的编译器,并且可以使用编译器如何处理实现定义的行为的内部知识,例如在有符号范围之外将无符号值转换为有符号类型的结果。