简体   繁体   中英

iterators in c++ template class

I have a little problem and I'm working on it for several hours but can't find a solution. Hope you will help me.

Here is my class:

#include <iostream>
#include <iterator>

template <typename T> class Array{
private:
    size_t size;
    T *newArray;

public:
    class Iterator:public std::iterator<std::output_iterator_tag, T>{
        T *p;
        public:
            Iterator(T*x):p(x){}
            T& operator*() {return *p;}

    };

    Array (size_t size = 10): size(size), newArray(new T[size]){};
    Iterator begin(){return (Iterator(newArray));}

    T printBegin(typename Array<T>::Iterator it){ return *it;}

    template <typename E>
    T printBegin(typename Array<E>::Iterator it){ return (T)*it;}

};

And here is Main:

using namespace std;

int main(){

    Array<int> x;
    Array<int> y;
    cout << y.printBegin(x.begin()); // prints 0 OK

    Array<double> p;
    // cout << p.printBegin(x.begin());

    return 0;
}

The first cout works fine but the line that is commented gives this : error: no matching function for call to 'Array<double>::printBegin(Array<int>::Iterator)'

I don't understand because the last line in my Array class matches (normally) for this function call

The problem is that you want to deduce the E in Array<E>::Iterator from x.begin() that is an Array<int>::Iterator . But that is simply not possible.

Your best option is probably to write:

template <typename IT>
T printBegin(IT it){ return (T)*it;}

If, for any reason, you need to use the E type, then it is better to add a nested typedef:

class Iterator:public std::iterator<std::output_iterator_tag, T>{
    public:
        typename T array_member_type;
        //...
};

And then:

template <typename IT>
T printBegin(IT it){
    typedef typename IT::array_member_type E;
    return (T)*it;
}

Wait! Your iterator derives from std::iterator so the typedef already exists. No need to redefine:

template <typename IT>
T printBegin(IT it){
    typedef typename IT::value_type E;
    return (T)*it;
}

Your question is very similar to another question about template deduction.

The compiler cannot deduct the type E from Array<E>::Iterator . Why should it be able to? Two different types E could share the same iterator type.

What you are really saying to the compiler is:

"Is there a type "E" for which Array<E>::Iterator is this type?"

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