Thread: Cannot declare STL iterators in custom templated classes!

  1. #1
    Registered User
    Join Date
    Mar 2006
    Posts
    3

    Exclamation Cannot declare STL iterators in custom templated classes!

    Suppose we have a templated class with an STL vector as a data member:

    Code:
    #include <vector>
    using namespace std;
    
    template <class T>
    class   Point
    {
       public:
          Point(T t);
          vector<T>   v;
    };
    
    template <class T>
    Point<T> :: Point(T t)
    {
       v.resize(3);
       for (vector<T>::iterator i = v.begin(); i < v.end(); i++)
          *i = t;
    }
    Compiling the above code with GCC 4.0.0 under Mac OS X (via Terminal), however, generates the following error messages:

    PowerBook:~/Desktop Maelstrom$ g++ main.cpp
    main.cpp: In constructor 'Point<T>::Point(T)':
    main.cpp:16: error: expected `;' before 'i' (Shown hilighted in red)
    main.cpp:16: error: 'i' was not declared in this scope


    I cannot find anything blatantly wrong with the this code. My first guess is that the STL vector iterator requires a concrete allocator object, but no allocator can be created since the precise type is undefined (because it's a template).

    Any ideas or solutions?
    Last edited by Maelstrom; 03-03-2006 at 02:36 AM.

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    The vector<T>::iterator should be declared as a typename, i.e.
    Code:
    for (typename vector<T>::iterator i = v.begin(); i < v.end(); i++)
    You might also prefer ++i instead of i++, but that's a minor point on efficiency that probably doesnt matter most of the time.

    EDIT:
    incidentally, you probably could just write it as:
    Code:
    template <class T>
    Point<T> :: Point(T t) : v(3, t) {}
    Last edited by laserlight; 03-03-2006 at 02:40 AM.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Registered User
    Join Date
    Mar 2006
    Posts
    3
    Quote Originally Posted by laserlight
    The vector<T>::iterator should be declared as a typename, i.e.
    Code:
    for (typename vector<T>::iterator i = v.begin(); i < v.end(); i++)
    You might also prefer ++i instead of i++, but that's a minor point on efficiency that probably doesnt matter most of the time.

    EDIT:
    incidentally, you probably could just write it as:
    Code:
    template <class T>
    Point<T> :: Point(T t) : v(3, t) {}
    Thanks!

    The addition of "typename" specifies that the statement "vector<T>::iterator i" should be treated as a declaration, not a function call, correct?

  4. #4
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    The addition of "typename" specifies that the statement "vector<T>::iterator i" should be treated as a declaration, not a function call, correct?
    From what I understand, here the compiler cannot be sure that vector<T>::iterator is a type name. The use of the typename keyword clarifies that it really is a type name.

    I think the use of the constructor initialisation list is simpler (and more efficient anyway), so you might want to consider using it instead of your explicit iteration over the vector to copy the elements.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  5. #5
    Registered User
    Join Date
    Mar 2006
    Posts
    3
    Quote Originally Posted by laserlight
    From what I understand, here the compiler cannot be sure that vector<T>::iterator is a type name. The use of the typename keyword clarifies that it really is a type name.

    I think the use of the constructor initialisation list is simpler (and more efficient anyway), so you might want to consider using it instead of your explicit iteration over the vector to copy the elements.
    Don't worry, that loop initialization was just to illustrate the problem I encountered whenever I tried to traverse an STL vector with iterators. Thanks, though :-)

  6. #6
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Unrelated to the original problem (which, as laserlight said, is addressed by using typename), but it is also a good idea to avoid having "using namespace std;" in any header files.......

  7. #7
    Registered User
    Join Date
    Apr 2003
    Posts
    2,663
    The addition of "typename" specifies that the statement "vector<T>::iterator i" should be treated as a declaration, not a function call, correct?
    How would:

    vector<T>::iterator i

    be a function call? A function call is characterized by having "()" somewhere, e.g.:

    myFunc(10, "age");

    The typename keyword tells the compiler that in this code fragment:

    vector<T>::iterator

    'iterator' is not to be interpreted as a static data member of vector<T>. That looks like the format for refering to a static data member--even though interpreting it like that would not make sense in the code. Instead, the 'typename' keyword tells the compiler to look inside the vector class for a typedef of the name 'iterator' and use that type as the type of the variable 'i'. So, in one case, the compiler retrieves the value of a static data member from the class, and in the other the compiler retrieves a type from the class.
    Last edited by 7stud; 03-03-2006 at 03:37 PM.

  8. #8
    Devil's Advocate SlyMaelstrom's Avatar
    Join Date
    May 2004
    Location
    Out of scope
    Posts
    4,079
    Quote Originally Posted by grumpy
    but it is also a good idea to avoid having "using namespace std;" in any header files.......
    Quote Originally Posted by Maelstrom
    main.cpp:16: error: 'i' was not declared in this scope
    While good advice, grumpy, I don't think it's pertinent here. Unless I missed somewhere where he said this was actually going in a header file.
    Sent from my iPadŽ

  9. #9
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by SlyMaelstrom
    While good advice, grumpy, I don't think it's pertinent here. Unless I missed somewhere where he said this was actually going in a header file.
    You missed nothing.

    I was responding to the fact of a using directive before a class declaration. That's sort-of OK in small programs or code samples but, as things get better and the project is broken into multiple source and header files, the first thing that will happen by default will be a using directive floating around in a header file .......

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Vectors and custom classes
    By cunnus88 in forum C++ Programming
    Replies: 16
    Last Post: 05-12-2006, 05:11 AM
  2. Custom container should expand STL containers?
    By LinuxCoder in forum C++ Programming
    Replies: 3
    Last Post: 04-03-2006, 02:05 PM
  3. Passing custom classes as arguments
    By Sfpiano in forum C++ Programming
    Replies: 5
    Last Post: 07-13-2005, 08:26 AM
  4. How To use vectors for custom classes
    By johnnyd in forum C++ Programming
    Replies: 14
    Last Post: 03-25-2003, 10:04 PM
  5. STL Vector and Custom Struct!
    By Unregistered in forum C++ Programming
    Replies: 3
    Last Post: 06-23-2002, 07:58 AM