Friday, May 6, 2011

Failing to use stl containers in templated functions/classes

When I try and compile the following code...

#include <vector>

template <class T> void DoNothing()
{
    std::vector<T>::iterator it;
}

int main(int argc, char**argv)
{
    return 0;
}

g++ says:

test.cpp:5: error: expected `;' before ‘it’

And I don't understand why this is a problem. If I replace it with std::vector<int>::iterator, say, it works fine as expected.

As you can see i'm not instantiating the function, so g++ must have a problem with the template definition itself, but I can't see how its invalid.

Thanks for any advice about whats going on.

NB I'm actually trying to write a templated class and having issues with a map rather than a vector, but this is the simplest test case for my problem.

From stackoverflow
  • Does typename std::vector<T>::iterator it; work?

    EDIT: change template to typename ... got my keywords mixed up.

  • You need to use the typename keyword because the std::vector<T>::iterator type is dependent on the template parameter:

    template <class T> void DoNothing()
    {
        typename std::vector<T>::iterator it;
    }
    

    It can actually be confusing when you need to use typename and when you don't need it (or are even not permitted to use it). This article has a decent overview:

    DaedalusFall : Thanks! The article helps also, though It still seems strange that the interpretation isn't left until instantiation.
    Gastón : Thanks for the answer Michael, it helped me too. I've had the same question for a long time and now I know when to use the typename keyword. The article sure helped.
    Johannes Schaub - litb : While some dependent names need typename in front of them, others don't need it. C++03, for example, says that in a template: template struct F { class A { }; void f() { A a; } }; the type-name "A" is dependent, since it is equivalent to saying F::A and F::A (and affects name-lookup at instantiation context). But another paragraph then says if a type-member is named using an unqualified name, typename is not required. See 14.6/6 and the new paragraph 14.6.1/2d in c++03. And C++1x introduces the concept of a member-of-the-current-instantiation where then typename is not required...
    Johannes Schaub - litb : I found that in addition, http://womble.decadentplace.org.uk/c++/template-faq.html is a very nice template faq to help with these confusing rules
  • I agree it is confusing. Without the typename keyword, the name would be considered a static member. The book C++ Templates by Vandevoorde and Josuttis explains this in detail.

0 comments:

Post a Comment

Note: Only a member of this blog may post a comment.