简体   繁体   中英

Compile error on begin() method of a class

Tried to create a class to keep track of packets within the last 2 seconds, but got compile error. Any ideas? Thanks.

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

Here is the little class:

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

You need to use the iterator of the container as the return type.

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

Should be

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

Or in C++14

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

Match the return type to what you want to return.

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

UPDATE: the compiler told me that you have to create end() function as a member of class cEvents . It should be like this:

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

You've defined begin() to return some type named iterator , but you haven't defined what type that actually is.

The only type the compiler can find by that name is std::iterator , which is a class template, so you can't use it without a template parameter list (and it's probably not what you want in this case anyway).

In this case, it looks to me like you probably want your begin() (and end() ) to return iterators into the list<pair<double, int>> that the object contains, so you'd do something like:

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

...or, better still:

typedef decltype(l)::iterator iterator;

...or equivalently (but more readably, at least in some people's view):

using iterator = decltype(l)::iterator;

Then, since you've defined what iterator means, you can use the name as the return type of your function (or as a parameter, etc.) Given that you apparently have something that acts/works like a collection anyway, you'd probably be better off defining the other "standard" types for a collection as well (eg, typedef std::pair<double, int> value_type; as well.

I would advise against directly specifying std::list<std::pair<double, int>>::iterator as the return type. This does work, but it contains substantial redundancy. You always want that return type to be the same as the iterator type for the collection, so if you change your mind and use some other collection instead of list , the return type of the function needs to change to match. Using decltype(l)::iterator makes that automatic, where using std::list<std::pair<double, int>>::iterator requires that you do manual editing to keep the types in sync.

I should probably add that in this particular case, I think making it easy to change to a different type as easily as possible is more important than usual. Specifically, using std::list is a mistake much more often than not, so unless this is throwaway code, chances of wanting to change to a different container are quite high.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM