C++中map迭代器问题

3
我在以下代码中遇到了一个奇怪的错误:

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;
}

正如您所见,这只是一个简单的代码,用于计算映射中平均分数。我在在线编译器上测试过它,并且它可以正常工作,但是当我尝试在我的计算机上编译它时(我正在使用CodeBlocks和GNU GCC编译器),我遇到了以下错误: ``` error: conversion from 'std::map, float>::const_iterator {aka std::_Rb_tree_const_iterator, float> >}' to non-scalar type 'std::map, float>::iterator {aka std::_Rb_tree_iterator, float> >}' requested| ```
2个回答

10

您有一个const函数,尝试迭代我假设是一个成员变量(marks)。 确保使用const迭代器:

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

1
我的答案也是这个。你可以看一下这个链接:http://duramecho.com/ComputerInformation/WhyHowCppConst.html - Joshua Behrens
2
顺便说一下,如果使用C++11,请使用marks.cbegin()marks.cend() - WhozCraig
谢谢,我对C++还很陌生,无法解决这个问题。错误信息也没有什么帮助。 - V Sebi
@VSebi:如果你以前没有见过它们,它们可能有点神秘,但是一旦你有了训练有素的眼睛,这个错误就会变得非常明显(无论是直接或间接地)尝试使用错误的迭代器类型。一旦你看到const_iterator这个词,那么你首先要做的就是检查容器的类型以及你是否处于const上下文中。然后所有的事情都会在几秒钟内落实。:) 这需要实践。 - Lightness Races in Orbit
@Lightness 或者 std::accumulate,无论是C++11还是不是(尽管使用lambda表达式确实使得在这种情况下使用算法更加可接受) - Praetorian

2
另一个答案展示了如何修复错误,但是这里有另一种使用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();
}

此外,异常规范已被弃用。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接