在类的begin()方法上编译错误

时间:2015-12-09 16:03:20

标签: c++

尝试创建一个类来跟踪最近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;
}

3 个答案:

答案 0 :(得分:4)

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

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

应该是

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

或者在C ++ 14中

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

答案 1 :(得分:2)

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

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

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

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

答案 2 :(得分:1)

您已定义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的含义,您可以使用该名称作为函数的返回类型(或作为参数等)。鉴于您显然有某些行为/无论如何,你的工作就像一个集合,你最好定义另一个&#34;标准&#34;集合的类型也是如此(例如,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通常是很多错误,所以除非这是一次性代码,否则想要更改为不同容器的可能性非常高。