微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何在C ++中实现迭代器?

如何解决如何在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 举报,一经查实,本站将立刻删除。