减去无符号整数的有符号结果?
Signed result of subtracted unsigned integers?
我正在尝试创建一个类似于 vector<string>
的 class 和另一个与其迭代器类似的 class (纯粹作为 C++ Primer 的练习(练习 14.28 对于那些感兴趣的人) ).迭代器 class 通过使用 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 中。我不知道如何定义我的 return 类型,以便如果 rhs (y) 在序列中比 lhs (x) 更远,正确的负值是 returned(存储在 z ).
我认为 vector<string>::difference_type
可能会这样做,但我发现 size_type
代表一个 32 位无符号整数,而 difference_type
代表一个 32 位有符号整数,所以会有用有符号整数环绕是一个错误,这是未定义的行为——即使在我的电脑上它产生了正确的结果。我可以 static_cast
一切到 long long int
和 return 一个 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);
}
标准库的实际实现可能不一定需要这样做,因为它们通常针对特定的编译器,并且可以使用编译器如何处理实现定义的行为(例如转换结果)的内部知识在有符号范围之外时将无符号值转换为有符号类型。
我正在尝试创建一个类似于 vector<string>
的 class 和另一个与其迭代器类似的 class (纯粹作为 C++ Primer 的练习(练习 14.28 对于那些感兴趣的人) ).迭代器 class 通过使用 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 中。我不知道如何定义我的 return 类型,以便如果 rhs (y) 在序列中比 lhs (x) 更远,正确的负值是 returned(存储在 z ).
我认为 vector<string>::difference_type
可能会这样做,但我发现 size_type
代表一个 32 位无符号整数,而 difference_type
代表一个 32 位有符号整数,所以会有用有符号整数环绕是一个错误,这是未定义的行为——即使在我的电脑上它产生了正确的结果。我可以 static_cast
一切到 long long int
和 return 一个 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);
}
标准库的实际实现可能不一定需要这样做,因为它们通常针对特定的编译器,并且可以使用编译器如何处理实现定义的行为(例如转换结果)的内部知识在有符号范围之外时将无符号值转换为有符号类型。