Thread: Adding iterators to a class template

  1. #1
    Optics with a Twist skewray's Avatar
    Join Date
    Dec 2006
    Location
    South Pasadena, CA
    Posts
    36

    Adding iterators to a class template

    I am trying to add an iterator to a class template. The class is not much more than an encapsulated standard library vector, which some added features. The compiler chokes pretty hard on the snippet below. Any tips appreciated, or just point me towards an online example of this somewhere. Much thanks!
    Code:
    #ifndef POLYNOMIAL_INCLUDE
    #define POLYNOMIAL_INCLUDE
    
    #include <vector>
    
    template <class T>
    class Polynomial
        {
    public:
        // other stuff goes here, chopped out for brevity
    
        typedef std::vector<T>::iterator iterator ;
        typedef std::vector<T>::const_iterator const_iterator ;
        typedef std::vector<T>::reverse_iterator reverse_iterator ;
        typedef std::vector<T>::const_reverse_iterator const_reverse_iterator ;
        iterator begin() const ;
        iterator end() const ;
    
    private:
        std::vector<T> terms_ ;
        } ;
    
    template <typename T> Polynomial<T>::iterator
    Polynomial<T>::begin() const
        {
        return terms_.begin() ;
        }
    
    template <typename T> Polynomial<T>::iterator
    Polynomial<T>::end() const
        {
        return terms_.end() ;
        }
    
    #endif // POLYNOMIAL_INCLUDE

  2. #2
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Code:
    #ifndef POLYNOMIAL_INCLUDE
    #define POLYNOMIAL_INCLUDE
    
    #include <vector>
    
    template <class T>
    class Polynomial
        {
    public:
        // other stuff goes here, chopped out for brevity
    
        typedef typename std::vector<T>::iterator iterator ;
        typedef typename std::vector<T>::const_iterator const_iterator ;
        typedef typename std::vector<T>::reverse_iterator reverse_iterator ;
        typedef typename std::vector<T>::const_reverse_iterator const_reverse_iterator ;
        iterator begin() const ;
        iterator end() const ;
    
    private:
        std::vector<T> terms_ ;
        } ;
    
    template <typename T> typename Polynomial<T>::iterator
    Polynomial<T>::begin() const
        {
        return terms_.begin() ;
        }
    
    template <typename T> typename Polynomial<T>::iterator
    Polynomial<T>::end() const
        {
        return terms_.end() ;
        }
    
    #endif // POLYNOMIAL_INCLUDE

  3. #3
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    However, I'd personally prefer a method which returns a const reference to the terms vector. That would give the caller maximum flexibility as well as cut down the wrapper code you need to write.

  4. #4
    Optics with a Twist skewray's Avatar
    Join Date
    Dec 2006
    Location
    South Pasadena, CA
    Posts
    36
    That works much better. Thanks, although I actually don't understand what the addition of the typename keyword does.

    Wouldn't returning a reference to a vector then be implementation dependent? If I want to be able to change my implementation to be, say, a linked list for a sparse polynomials, the caller's code could be in trouble if it assumed a vector.

  5. #5
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Quote Originally Posted by skewray View Post
    That works much better. Thanks, although I actually don't understand what the addition of the typename keyword does.

    Wouldn't returning a reference to a vector then be implementation dependent? If I want to be able to change my implementation to be, say, a linked list for a sparse polynomials, the caller's code could be in trouble if it assumed a vector.
    typename tells the compiler that the name that follows it is a type rather than something else like a function or variable name...

    I agree with you there; exposing the vector rather than typedefing it away makes it much harder to change to something else once other code starts using it.

  6. #6
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by skewray View Post
    That works much better. Thanks, although I actually don't understand what the addition of the typename keyword does.

    Wouldn't returning a reference to a vector then be implementation dependent? If I want to be able to change my implementation to be, say, a linked list for a sparse polynomials, the caller's code could be in trouble if it assumed a vector.
    Properly generic code won't care what the type is. In particular, this example doesn't care what the type is:

    Code:
    std::for_each(poly.terms().begin(), poly.terms().end(), ...);
    If the type of poly.terms() changes, it's no problem.
    Last edited by brewbuck; 01-02-2008 at 10:51 PM.

  7. #7
    Optics with a Twist skewray's Avatar
    Join Date
    Dec 2006
    Location
    South Pasadena, CA
    Posts
    36
    Quote Originally Posted by cpjust View Post
    typename tells the compiler that the name that follows it is a type rather than something else like a function or variable name...
    I assume that since I can figure out that it is a typename without the help of the extra keyword, this means that the compiler parser needs more than one token of look-ahead in order to figure out what is going on? Or is there some other meaningful interpretation of the code that I am missing when the typename keyword is omitted?

  8. #8
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by skewray View Post
    I assume that since I can figure out that it is a typename without the help of the extra keyword, this means that the compiler parser needs more than one token of look-ahead in order to figure out what is going on? Or is there some other meaningful interpretation of the code that I am missing when the typename keyword is omitted?
    There are at least a few obscure cases where a code fragment could be syntactically correct whether the named entity is a typename or an identifier. These cases are why typename was invented. For consistency, it was decided that it should be required everywhere when looking up dependent typenames inside template scopes.

    Consider this case:

    Code:
    typename A<X>::B foo() { }
    Although it is obvious that A<X>::B can be nothing other than a typename (since an identifier is not legal as the return type of a function), we are required to use it anyway. Just how it is.

  9. #9
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by skewray View Post
    Wouldn't returning a reference to a vector then be implementation dependent? If I want to be able to change my implementation to be, say, a linked list for a sparse polynomials, the caller's code could be in trouble if it assumed a vector.
    You just specify that the terms() method returns a reference to some container type. Make this type available to the caller as "typedef whatever terms_container_type" or some other name.

    Then the caller understands that a terms_container_type is returned, whatever that happens to be.

    This does force at least a recompile of client software if/when you change the implementation, but that's true whenever you change even the private details of a class (unless you are using the "pimpl" idiom).

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Default class template problem
    By Elysia in forum C++ Programming
    Replies: 5
    Last Post: 07-11-2008, 08:44 AM
  2. deriving classes
    By l2u in forum C++ Programming
    Replies: 12
    Last Post: 01-15-2007, 05:01 PM
  3. template class default constructor problem
    By kocika73 in forum C++ Programming
    Replies: 3
    Last Post: 04-22-2006, 09:42 PM
  4. Prime Number Generator... Help !?!!
    By Halo in forum C++ Programming
    Replies: 9
    Last Post: 10-20-2003, 07:26 PM
  5. Operator overloading in template classes
    By moejams in forum C++ Programming
    Replies: 5
    Last Post: 07-21-2003, 05:16 PM