我在C++中遇到了一个非常奇怪的set迭代器问题.
set<string> dict;
dict.insert("hello");
dict.insert("my");
int maxLen = INT_MIN;
set<string>::iterator itr;
for (itr=dict.begin(); itr!=dict.end(); itr++) {
int len = (*itr).length();
if ( len > maxLen )
maxLen = (*itr).length();
}
Run Code Online (Sandbox Code Playgroud)
这段代码帮助我将maxLen设置为5,这是单词集中最长单词的长度.
set<string> dict;
dict.insert("hello");
dict.insert("my");
int maxLen = INT_MIN;
set<string>::iterator itr;
for (itr=dict.begin(); itr!=dict.end(); itr++) {
if ( (*itr).length() > maxLen )
maxLen = (*itr).length();
}
Run Code Online (Sandbox Code Playgroud)
但是,这段代码无法给我正确的结果.运行代码后,maxLen仍然是INT_MIN的值.基本上没什么变化,除了我不再使用变量来保存(*itr).length()的值.
这对我来说很奇怪.我错过了什么吗?我只想澄清我对迭代器使用的怀疑.
非常感谢!
我认为这里的问题是该string::length函数返回一个无符号类型,而int您正在使用的类型已签名.在有符号值和无符号值之间进行比较时,有符号值始终首先转换为无符号值.在你的情况下,转换INT_MIN到一个无符号的价值,所以采取了最大可能的无符号数,因为对位模式INT_MIN和UINT_MAX是相同的.
这是第一次使用的原因是无符号值int在分配给临时变量时被强制转换为s.
要解决此问题,请在以下位置添加强制转换:
for (itr=dict.begin(); itr!=dict.end(); itr++) {
if ( int((*itr).length()) > maxLen )
maxLen = (*itr).length();
}
Run Code Online (Sandbox Code Playgroud)
只要你在这里,你可以在这里做很多其他的风格修复,例如
++为增量++效率,->代替(*).,这显示在这里:
for (set<string>::iterator itr = dict.begin(); itr != dict.end(); ++itr) {
if (int(itr->length()) > maxLen) {
maxLen = itr->length();
}
}
Run Code Online (Sandbox Code Playgroud)
或者,如果您有一个符合C++ 11的编译器,则使用基于范围的for循环:
for (const auto& val: dict) {
if (int(val.length()) > maxLen) {
maxLen = val.length();
}
}
Run Code Online (Sandbox Code Playgroud)
希望这可以帮助!