Generic iterator utility functions

Discussion in 'C++' started by Carlo Milanesi, Nov 15, 2003.

  1. Let's say I want to write the following function,

    void f(const list<int> &l, const vector<int> &v) {
    cout << get_second(l) << '\n';
    cout << get_second(v) << '\n';
    cout << get_nth(l, 2) << '\n';
    cout << get_nth(v, 2) << '\n';
    }

    that prints the second and third (counting from zero) items of given
    list and vector.
    For such a purpose I need to write the generic functions (i.e. function
    templates) 'get_second' and'get_nth' that, respectively, return the
    second and the n-th item of the given collection. Possible
    implementations of these two functions are the following ones:

    template<typename Coll>
    inline typename Coll::value_type get_second(const Coll &coll) {
    // return *++(coll.begin()); // Wrong.
    // return *(coll.begin() + 1); // Wrong.
    typename Coll::const_iterator it = coll.begin();
    advance(it, 1);
    return *it;
    }

    template<typename Coll, typename Distance>
    inline typename Coll::value_type get_nth(
    const Coll &coll, Distance d) {
    typename Coll::const_iterator it = coll.begin();
    advance(it, d);
    return *it;
    }

    As noted in the code comments, the use of the operator '++' is wrong
    (although some compilers accept it) as the function 'begin' shouldn't
    return an l-value; and the use of the operator'+' is wrong for
    non-random iterators, like those of list. So, the quickest solution I
    found was that rather cumbersome code.
    But I think that a better solution would be to define the following
    function templates:

    // Return the successor of the given input iterator.
    template<typename InputIterator>
    inline InputIterator succ(InputIterator it) {
    return ++it;
    }

    // Return the predecessor of the given bidirectional iterator.
    template<typename BidirectionalIterator>
    inline BidirectionalIterator pred(BidirectionalIterator it) {
    return --it;
    }

    // Return an input iterator moved from the given input iterator
    // by the given distance.
    template<typename InputIterator, typename Distance>
    inline InputIterator adv(InputIterator it, Distance d) {
    advance(it, d);
    return it;
    }

    and then use them in the following function templates:

    template<typename Coll>
    inline typename Coll::value_type get_second(const Coll &coll) {
    return *succ(coll.begin());
    }

    template<typename Coll, typename Distance>
    inline typename Coll::value_type get_nth(const Coll &coll,
    Distance d) {
    return *adv(coll.begin(), d);
    }

    Is it a good idea to keep the functions 'succ', 'prec' and 'adv' in my
    toolkit of generic utility functions, or are there better solutions?

    --
    Carlo Milanesi
    http://digilander.libero.it/carlmila
    Carlo Milanesi, Nov 15, 2003
    #1
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Hendrik Maryns
    Replies:
    18
    Views:
    1,404
  2. greg
    Replies:
    6
    Views:
    448
    Dietmar Kuehl
    Jul 17, 2003
  3. Gordon Airporte

    Generic utility class for passing data

    Gordon Airporte, Oct 29, 2005, in forum: Python
    Replies:
    5
    Views:
    398
    Chris Smith
    Oct 29, 2005
  4. Tony Johansson

    generic functions(template functions)

    Tony Johansson, Aug 16, 2005, in forum: C++
    Replies:
    3
    Views:
    399
    Srini
    Aug 16, 2005
  5. Replies:
    6
    Views:
    634
    Jim Langston
    Oct 30, 2005
Loading...

Share This Page