【问题标题】:C++ map iterator issueC ++映射迭代器问题
【发布时间】:2014-01-06 17:56:39
【问题描述】:

我在以下代码中有一个奇怪的错误:

float Student::getAverageMark() const throw (NoMarkException)
{
    int sum = 0;
    int count = 0;
    for(map<string, float>::iterator iter = marks.begin(); iter != marks.end(); ++iter) {
        sum += iter->second;
        count++;
    }
    return sum/count;
}

如您所见,这并没有什么特别之处,它是一个计算地图中平均标记的简单代码。我在一个在线编译器中对此进行了测试,它可以工作,但是当我尝试在我的机器上编译它时(我正在使用带有 GNU GCC 编译器的 CodeBlocks)我得到了这个错误:

错误:从 'std::map, float>::const_iterator {aka std::_Rb_tree_const_iterator, float> >}' 转换为非标量类型 'std::map, float>::iterator {aka std: :_Rb_tree_iterator, float> >}' 请求|

【问题讨论】:

    标签: c++ gcc map iterator


    【解决方案1】:

    您有一个 const 函数试图迭代我假设的成员变量(标记)。 确保使用 const 迭代器:

    for(map<string, float>::const_iterator iter = marks.begin();
    

    【讨论】:

    • 这也是我的答案。你可以看看这个:duramecho.com/ComputerInformation/WhyHowCppConst.html
    • +1 使用 C++11 时,请使用 marks.cbegin()marks.cend()
    • 谢谢,我对 C++ 还是很陌生,无法弄清楚这一点。错误消息也没有多大帮助。
    • @VSebi:当您以前从未见过它们时,它们有点神秘,但是一旦您有训练有素的眼睛,这对于(间接或直接)尝试使用错误的迭代器类型。一旦你看到const_iterator 这个词,你要做的第一件事就是检查容器的类型以及你是否在const 上下文中。然后一切都在几秒钟内到位。 :) 随练习而来。
    • @Lightness 或 std::accumulate,C++11 与否(尽管在这种情况下,使用 lambdas 确实使使用算法更容易接受)\
    【解决方案2】:

    other answer 显示了如何修复错误,但这是使用std::accumulate 计算平均值的另一种方法。使用这种方法,您无需担心迭代器类型等问题,也可以消除循环。

    float Student::getAverageMark() const throw (NoMarkException)
    {
        if(marks.empty()) {
            return 0;
        }
        return std::accumulate(marks.begin(), marks.end(), 0.0f,
                               [](float acc, decltype(marks)::value_type const& elem) {
                                  return acc + elem.second;
                               }) / marks.size();
    }
    

    另外,exception specifications 已被弃用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-04-15
      • 2011-07-31
      • 1970-01-01
      • 2011-05-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多