类的begin()方法出现编译错误

Compile error on begin() method of a class

本文关键字:编译 错误 方法 begin 类的      更新时间:2023-10-16

试图创建一个类来跟踪最后2秒内的数据包,但出现编译错误。有什么想法吗?谢谢

g++ -std=c++11 map2.cc 
map2.cc:20:2: error: invalid use of template-name ‘std::iterator’ without an argument list
  iterator begin() { return l.begin(); }

这是一个小类:

#include <iostream>
#include <string>
#include <list>
#include <unordered_map>
using namespace std;
class cEvents {
public:
    list<pair<double, int>> l;
    int add(double ts, int pktNum, double maxTime) {
        l.push_back(make_pair(ts, pktNum));
        pair<double, int> tmp;
        while (1) {
            tmp = l.front();
            if ((ts - tmp.first) < maxTime) break;
            l.pop_front();
        }
        return l.size();
    }
    iterator begin() { return l.begin(); }
};
int main () {
    cEvents e;
    cout << e.add(0, 1, 2) << endl;
    cout << e.add(0.1,2, 2) << endl;
    cout << e.add(0.2,3, 2) << endl;
    cout << e.add(0.5,4, 2) << endl;
    cout << e.add(1.2,5, 2) << endl;
    cout << e.add(1.7,6, 2) << endl;
    for (auto x : e) {
        //cout << x.first << " " << x.second << endl;
    }
    cout << e.add(2.2,7, 2) << endl;
    cout << e.add(3.2,8, 2) << endl;
    return 0;
}

您需要使用容器的迭代器作为返回类型。

iterator begin() { return l.begin(); }

应该是

list<pair<double, int>>::iterator begin() { return l.begin(); }

或者在C++14 中

auto begin() { return l.begin(); }

将返回类型与您想要返回的内容相匹配。

试试这个:list<pair<double, int>>::iterator begin() { return l.begin(); }

UPDATE:编译器告诉我,您必须创建end()函数作为class cEvents的成员。应该是这样的:

list<pair<double, int>>::iterator end() { return l.end(); }

您已经定义了begin()来返回一些名为iterator的类型,但您还没有定义它实际上是什么类型。

编译器能找到的唯一类型是std::iterator,这是一个类模板,所以如果没有模板参数列表,你就无法使用它(在这种情况下,它可能不是你想要的)。

在这种情况下,在我看来,您可能希望begin()(和end())将迭代器返回到对象所包含的list<pair<double, int>>中,因此您可以执行以下操作:

typedef list<pair<double, int>>::iterator iterator;

或者,更好的是:

typedef decltype(l)::iterator iterator;

或者等效地(但更容易阅读,至少在一些人看来):

using iterator = decltype(l)::iterator;

然后,既然您已经定义了iterator的含义,您就可以将名称用作函数的返回类型(或参数等)。考虑到您显然拥有与集合类似的行为/工作方式,您可能最好也为集合定义其他"标准"类型(例如,typedef std::pair<double, int> value_type;)。

我建议不要直接将std::list<std::pair<double, int>>::iterator指定为返回类型。这确实有效,但其中包含大量冗余。您总是希望返回类型与集合的迭代器类型相同,因此,如果您改变主意,使用其他集合而不是list,则需要更改函数的返回类型以匹配。使用decltype(l)::iterator会自动执行,而使用std::list<std::pair<double, int>>::iterator需要手动编辑以保持类型同步。

我可能应该补充一点,在这种特殊情况下,我认为尽可能容易地更改为不同类型比平时更重要。具体来说,使用std::list通常是一个错误,所以除非这是一次性代码,否则想要更改到不同容器的几率很高。