0

I am getting compilation error , please help i am not able to resolve it

 class A {
        public :
        A() {} 
        virtual ~A() {}

        int getID() { return m_id; }
        void setID(int id) { m_id = id ; }

        private:
        int m_id ;
    };    


    class B : public A {

    };


    class C: public A {

    };

    template<class T>
    T* returnObject(vector<T*>& vec, int id)
    {
        for(vector<T*>::iterator itr =vec.begin();  itr != vec.end() ; ++itr)
        {
            if(id == (*itr)->getID()) return (*itr);
        }
        return NULL;
    }

    int main() 
    {
        vector<B*> b1;
        vector<C*> c1;

        B *b = new B();
        b->setID(10);
        b1.push_back(b);
        b = new B();
        b->setID(20);
        b1.push_back(b);
        b = new B();
        b->setID(30);
        b1.push_back(b);

        C *c = new C();
        c->setID(6);
        c1.push_back(c);
        c = new C();
        c->setID(12);
        c1.push_back(c);
        c = new C();
        c->setID(18);
        c1.push_back(c);

        B *bcd = returnObject<B>(b1,30);

        cout<< bcd <<endl ;

        return 0;
    }

I am getting compilation error

castEx.cpp: In function `T* returnObject(std::vector<T*, std::allocator<T*> >&, int)':
castEx.cpp:29: error: expected `;' before "itr"
castEx.cpp:29: error: `itr' was not declared in this scope
castEx.cpp: In function `T* returnObject(std::vector<T*, std::allocator<T*> >&, int) [with T = B]':
castEx.cpp:61:   instantiated from here
castEx.cpp:29: error: dependent-name ` std::vector<T*,std::allocator<T*> >::iterator' is parsed as a non-type, but instantiation yields a type
Petr
  • 9,051
  • 1
  • 25
  • 47
Avinash Kumar
  • 589
  • 2
  • 6
  • 24

1 Answers1

2

The problem is that vector<T*>::iterator depends on a template parameter. The compiler doesn't know that every single std::vector specialization has an iterator member which is a type, so you need to explicitly state that it is a type:

for(typename vector<T*>::iterator itr =vec.begin();  itr != vec.end() ; ++itr)
//  ^^^^^^^^

See this question for more information about typename.

Of course, you could sidestep the whole issue in C++11 and just use auto:

for(auto itr =vec.begin();  itr != vec.end() ; ++itr)

Or range-based for loops:

for (auto&& element : vec)

Or std::find_if:

std::find_if(std::begin(vec), std::end(vec), 
            [id](auto&& el){ return id == el->getID() });

Although std::find_if returns std::end(vec) if the element is not found, rather than NULL.

Community
  • 1
  • 1
TartanLlama
  • 59,364
  • 11
  • 141
  • 183
  • 1
    or just use `auto`. Avoids all the confusion and is pretty clear in this case. Or even `for(T* item : vec) { /*...*/ }` – WorldSEnder Jun 19 '15 at 14:03