如何解决如何在C ++中实现迭代器?
using StringVec = std::vector<std::string>;
using StringIntMap = std::unordered_map<std::string,int>;
StringIntMap makeWordCounts(const StringVec& words) {
StringIntMap wordcount_map;
std::vector<std::string>::const_iterator iter = words.begin();
while(iter != words.end()) { //error message appears here
if(wordcount_map.count(iter)) {
wordcount_map[iter] = 1;
}else{
int value = wordcount_map.at(iter);
wordcount_map[iter] = value+1;
}
}
return wordcount_map;
}
错误消息: 没有可行的转换
'std::vector<std::string>::const_iterator' (aka '__wrap_iter<const
std::__1::basic_string<char> *>') to 'const
std::__1::unordered_map<std::__1::basic_string<char>,int,std::__1::hash<std::__1::basic_string<char> >,std::__1::equal_to<std::__1::basic_string<char> >,std::__1::allocator<std::__1::pair<const std::__1::basic_string<char>,int> > >::key_type' (aka 'const std::__1::basic_string<char>')
if(wordcount_map.count(iter)) {
谢谢您的帮助。
解决方法
看看您正在调用什么函数:
wordcount_map.count(iter) ^^^^^
现在,看看参数的类型:
size_type count( const Key& key ) const;
^^^^^^^^^^
请注意,该参数应该是映射的键。现在,看看地图的关键类型:
using StringIntMap = std::unordered_map<std::string,int>; ^^^^^^^^^^^
它是一个字符串。最后,看看您尝试传递给函数的参数类型:
std::vector<std::string>::const_iterator iter = words.begin(); ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
您看到问题了吗?您正在将迭代器传递给需要字符串的函数。那是完全错误的对象类型,甚至不能转换为期望的类型。这就是为什么出现错误的原因:
错误消息:没有从[迭代器]到[字符串]的可行转换
您尚未描述要执行的操作,但是鉴于迭代器指向一个字符串,并且您调用的函数需要一个字符串,我猜您想传递迭代器指向的字符串进入功能。要访问指向的字符串,您需要通过迭代器进行间接访问。这可以使用间接运算符实现:
*iter
P.S。如果进入了循环,它将永远不会结束(除非抛出了某些东西或进程终止了),因为iter
从未被修改过,因此无法更改结束条件。
此外,else
分支似乎总是抛出(这将终止循环)。
假设您要使用std::string
当前引用的words
向量的iter
元素作为wordcount_map
中的索引/关键字,那么您只需要使用iter
运算符解除对*
的引用即可。同样,就目前而言,您的while
循环不会对iter
变量进行任何修改;您可能需要在循环结束时在其上使用增量(++
)运算符:
using StringVec = std::vector<std::string>;
using StringIntMap = std::unordered_map<std::string,int>;
StringIntMap makeWordCounts(const StringVec& words)
{
StringIntMap wordcount_map;
std::vector<std::string>::const_iterator iter = words.begin();
while (iter != words.end()) {
if (wordcount_map.count(*iter)) { // Use * to dereference iter
wordcount_map[*iter] = 1; // ... and here
}
else {
int value = wordcount_map.at(*iter); // ...
wordcount_map[*iter] = value + 1; // ...
}
++iter; // Increment the iterator to move on to the next vector element
}
return wordcount_map;
}
但是,与其将++iter
作为一个单独的行添加到while
循环中,还可以使用for
循环:
for (std::vector<std::string>::const_iterator iter = words.begin(); iter != words.end(); ++iter) {
//...
或更简单的是,根本不使用显式迭代器;只需使用“基于范围的” for
循环即可:
for (auto str : words) {
if (wordcount_map.count(str)) {
wordcount_map[str] = 1;
}
else {
int value = wordcount_map.at(str);
wordcount_map[str] = value + 1;
}
}
,
正如其他答案所解释的那样,由于没有取消引用迭代器以访问它所引用的std::string
,所以您得到了编译器错误。
我只想补充一点,即使修复了该错误,您的代码中仍然存在逻辑错误:
-
您的循环根本没有增加迭代器,因此如果
words
向量不为空,它将无限循环地运行。 -
您的循环体是向后实现的。
std::unordered_map::count()
返回与请求的键匹配的元素的 number 。if
语句将0的数值视为false
,将任何其他数值视为true
。因此,如果count()
返回> 0
表示给定键确实存在,则您正在更新值为1的元素,将其先前的元素清除掉值。并且如果count()
返回0
表示给定键不存在,则您正在使用相同的键调用std::unordered_map::at()
,该键将失败并抛出{{1} }。
更正后的版本如下:
std::out_of_range
但是,此代码不必要地复杂且效率低下。可以大大简化为:
using StringVec = std::vector<std::string>;
using StringIntMap = std::unordered_map<std::string,int>;
StringIntMap makeWordCounts(const StringVec& words) {
StringIntMap wordcount_map;
StringVec::const_iterator iter = words.begin();
while (iter != words.end()) {
if (wordcount_map.count(*iter)) {
int value = wordcount_map.at(*iter);
wordcount_map[*iter] = value + 1;
}else{
wordcount_map[*iter] = 1;
}
++iter;
}
return wordcount_map;
}
基于范围的using StringVec = std::vector<std::string>;
using StringIntMap = std::unordered_map<std::string,int>;
StringIntMap makeWordCounts(const StringVec& words) {
StringIntMap wordcount_map;
for(const auto &word : words) {
wordcount_map[word]++;
}
return wordcount_map;
}
循环将为您处理迭代器。并且for
返回对元素值的引用,如果请求的键尚不存在,则会为您插入并初始化一个新元素。
该错误不在您认为的那一行。在其余代码的后面,您忘了取消引用iter
并在需要std::string
的地方传递了迭代器。修复:
if(wordcount_map.count(*iter)) {
wordcount_map[*iter] = 1;
}else{
int value = wordcount_map.at(*iter);
wordcount_map[*iter] = value+1;
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。