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

时间:2015-10-01 16:28:04

标签: c++ unsigned subtraction

我试图创建一个与vector<string>类似的类和另一个与其迭代器类似的类(纯粹作为C ++ Primer的练习(对于那些感兴趣的人,练习14.28))。迭代器类的工作原理是使用vector<string>::size_type成员(称为curr)来表示向量的索引。我不想粘贴整个作品,因为它很长,但在尝试为迭代器定义我自己的减法运算符时,我已达到某种程度的混乱。最终它应该像减去两个迭代器一样工作,并在必要时产生负值。我有这样定义的函数:

??? 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,但我觉得这有点过于暴力了。

1 个答案:

答案 0 :(得分:7)

使用的正确类型确实是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);
}

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