Function Objects with Iterators

Discussion in 'C++' started by gexarchakos, Feb 11, 2007.

  1. gexarchakos

    gexarchakos Guest

    Hi there,

    Please give me at least a hint...
    I have a problem implementing a function object with parameters two
    iterators. That is:

    A class 'node' produces messages using a routing policy. The routing
    policy needs to take the node's neighbours and return a subset of them
    based on several criteria. Each message may have different routing
    policy. Thus, the policy should be specified while the new message is
    produced. The policy should be a different class that can be inherited
    and be able to take the (begin,end) iterators of the neighbour list
    and return a std::stack of a subset of them.

    The node should not reveal any of its internal structures, not even
    the neighbours structure. This is why I created a templated function
    object but I do not know how to declare the two iterators to be
    general without having to specify their exact type.

    template<class _TYPE> class router {
    public:
    // function to take the start and end iterators of a container and
    return a subset of them in a stack.
    // it decides using further inheritance which routing policy will be
    used for each message
    std::stack<_TYPE> operator()(iterator _begin, iterator _end);
    };

    template<class _MSG, class _CLK> class node { //this is a node
    class with MESSAGE and CLOCK parameters
    private:
    // map holding node's neighbours and their expiry time
    std::map<node<_MSG, _CLK>*, _CLK> _fanin, _fanout;
    public:
    // function to produce a message ready to deliver with the actual
    content, expiry and routing policy
    node<_MSG, _CLK>& produce(_MSG _msg, _CLK _clock, router _rout);
    };

    The user of the node::produce funtion does not need to specify the
    exact iterator type since than would violate the principle of hiding
    the neighbour's structure.

    I need for the iterators a form so that I declare & define & use the
    produce function without having to specify std::map<node<_MSG, _CLK>*,
    _CLK>::iterator.

    Please, help me or post a an idea that has the same effect.

    Thanks in advance,
    -- George
     
    gexarchakos, Feb 11, 2007
    #1
    1. Advertising

  2. gexarchakos wrote:
    > Hi there,
    >
    > Please give me at least a hint...
    > I have a problem implementing a function object with parameters two
    > iterators. That is:
    >
    > A class 'node' produces messages using a routing policy. The routing
    > policy needs to take the node's neighbours and return a subset of them
    > based on several criteria. Each message may have different routing
    > policy. Thus, the policy should be specified while the new message is
    > produced. The policy should be a different class that can be inherited
    > and be able to take the (begin,end) iterators of the neighbour list
    > and return a std::stack of a subset of them.
    >
    > The node should not reveal any of its internal structures, not even
    > the neighbours structure. This is why I created a templated function
    > object but I do not know how to declare the two iterators to be
    > general without having to specify their exact type.
    >
    > template<class _TYPE> class router {
    > public:
    > // function to take the start and end iterators of a container and
    > return a subset of them in a stack.
    > // it decides using further inheritance which routing policy will be
    > used for each message
    > std::stack<_TYPE> operator()(iterator _begin, iterator _end);
    > };
    >
    > template<class _MSG, class _CLK> class node { //this is a node
    > class with MESSAGE and CLOCK parameters
    > private:
    > // map holding node's neighbours and their expiry time
    > std::map<node<_MSG, _CLK>*, _CLK> _fanin, _fanout;
    > public:
    > // function to produce a message ready to deliver with the actual
    > content, expiry and routing policy
    > node<_MSG, _CLK>& produce(_MSG _msg, _CLK _clock, router _rout);
    > };
    >
    > The user of the node::produce funtion does not need to specify the
    > exact iterator type since than would violate the principle of hiding
    > the neighbour's structure.
    >
    > I need for the iterators a form so that I declare & define & use the
    > produce function without having to specify std::map<node<_MSG, _CLK>*,
    > _CLK>::iterator.
    >
    > Please, help me or post a an idea that has the same effect.
    >
    > Thanks in advance,
    > -- George
    >


    I think I understand you.

    Write your template so that the iterator is the template parameter

    template<class _ITER>
    class router
    {
    public:
    std::stack<typename _ITER::value_type> operator()(_ITER begin,
    _ITER end);
    };

    All iterators have a member called value_type which is the type that the
    iterator refers to.

    John
     
    John Harrison, Feb 11, 2007
    #2
    1. Advertising

  3. gexarchakos

    gexarchakos Guest

    Many thanks John,

    this would be a possible solution but the problem that appears now is
    that when I call
    node<_MSG,_CLK>::produce(_msg, _clock, router<std::map<node<_MSG,
    _CLK>*,_CLK>::iterator>());
    I need to know that the neighbours are in a map structure so that to
    initialize the 'router' with this specific iterator.
    e.g. if i have a function

    void test() {
    ...
    node<int,int> _n;
    _n.produce(8,2,router<std::map<node<_MSG,
    _CLK>*,_CLK>::iterator>());
    }

    This is something I need to avoid. The test function is outside the
    class 'node' but still needs to know the neighbours structure.

    However, your solution had something that really helped:
    std::stack<typename _ITER::value_type> ... (good point)

    What if:
    class router {
    public:
    template<class _ITER> std::stack<typename _ITER::value_type>
    operator()(_ITER _begin, _ITER _end);
    };

    This, I think, would solve the problem above but poses a new one:
    template functions cannot be virtual so this posses some kind of
    inheritance problem...

    Any idea is welcome... and again many thanks John!

    -- George
     
    gexarchakos, Feb 11, 2007
    #3
  4. gexarchakos

    Alan Johnson Guest

    gexarchakos wrote:
    > What if:
    > class router {
    > public:
    > template<class _ITER> std::stack<typename _ITER::value_type>
    > operator()(_ITER _begin, _ITER _end);
    > };


    A problem you are bound to run into using "_ITER::value_type" is that
    pointers can be iterators, but obviously don't have a member called
    "value_type".

    Fortunately the standard anticipated this and provides an
    "iterator_traits" template to solve the problem. You use it like:
    std::iterator_traits<_ITER>::value_type

    For most iterators this just becomes "_ITER::value_type", but for
    pointer types it becomes the type the pointer points to.

    --
    Alan Johnson
     
    Alan Johnson, Feb 11, 2007
    #4
  5. gexarchakos

    red floyd Guest

    John Harrison wrote:
    > gexarchakos wrote:
    >> [redacted]
    >> template<class _TYPE> class router {
    >> public:
    >> // function to take the start and end iterators of a container
    >> and
    >> return a subset of them in a stack.
    >> // it decides using further inheritance which routing policy
    >> will be
    >> used for each message
    >> std::stack<_TYPE> operator()(iterator _begin, iterator _end);
    >> };
    >>
    >> template<class _MSG, class _CLK> class node { //this is a node
    >> class with MESSAGE and CLOCK parameters
    >> private:
    >> // map holding node's neighbours and their expiry time
    >> std::map<node<_MSG, _CLK>*, _CLK> _fanin, _fanout;
    >> public:
    >> // function to produce a message ready to deliver with the actual
    >> content, expiry and routing policy
    >> node<_MSG, _CLK>& produce(_MSG _msg, _CLK _clock, router _rout);
    >> };
    >>
    >> [redacted]

    > template<class _ITER>
    > class router
    > {
    > public:
    > std::stack<typename _ITER::value_type>
    > operator()(_ITER begin, _ITER end);
    > };
    >


    Both gexarchakos and John's code is improper. Any identifier with a
    leading underscore followed by an uppercase letter is reserved to the
    implementation.

    Use TYPE_, MSG_, CLK_, ITER_ instead.
     
    red floyd, Feb 12, 2007
    #5
  6. On Feb 12, 12:47 am, red floyd <> wrote:
    > John Harrison wrote:
    > > gexarchakos wrote:
    > >> [redacted]
    > >> template<class _TYPE> class router {
    > >> public:
    > >> // function to take the start and end iterators of a container
    > >> and
    > >> return a subset of them in a stack.
    > >> // it decides using further inheritance which routing policy
    > >> will be
    > >> used for each message
    > >> std::stack<_TYPE> operator()(iterator _begin, iterator _end);
    > >> };

    >
    > >> template<class _MSG, class _CLK> class node { //this is a node
    > >> class with MESSAGE and CLOCK parameters
    > >> private:
    > >> // map holding node's neighbours and their expiry time
    > >> std::map<node<_MSG, _CLK>*, _CLK> _fanin, _fanout;
    > >> public:
    > >> // function to produce a message ready to deliver with the actual
    > >> content, expiry and routing policy
    > >> node<_MSG, _CLK>& produce(_MSG _msg, _CLK _clock, router _rout);
    > >> };

    >
    > >> [redacted]

    > > template<class _ITER>
    > > class router
    > > {
    > > public:
    > > std::stack<typename _ITER::value_type>
    > > operator()(_ITER begin, _ITER end);
    > > };

    >
    > Both gexarchakos and John's code is improper. Any identifier with a
    > leading underscore followed by an uppercase letter is reserved to the
    > implementation.
    >
    > Use TYPE_, MSG_, CLK_, ITER_ instead.


    Thank you red floyd for your comment... One more thing I didn't know!
    However, any compilation/building phase of my code didn't catch this.
    Anyway, good to know for the future.

    Thanks,
    -- George
     
    George Exarchakos, Feb 12, 2007
    #6
  7. On Feb 11, 11:35 pm, Alan Johnson <> wrote:
    > gexarchakos wrote:
    > > What if:
    > > class router {
    > > public:
    > > template<class _ITER> std::stack<typename _ITER::value_type>
    > > operator()(_ITER _begin, _ITER _end);
    > > };

    >
    > A problem you are bound to run into using "_ITER::value_type" is that
    > pointers can be iterators, but obviously don't have a member called
    > "value_type".
    >
    > Fortunately the standard anticipated this and provides an
    > "iterator_traits" template to solve the problem. You use it like:
    > std::iterator_traits<_ITER>::value_type
    >
    > For most iterators this just becomes "_ITER::value_type", but for
    > pointer types it becomes the type the pointer points to.
    >
    > --
    > Alan Johnson


    Hi Alan,

    thank you for your reply. I have the Stroupstrup book in front of me
    and I try to figure out how exactly I am going to use the
    iterator_traits. My only problem is that it is again a templated-based
    solution which is perfectly fine except for the case I want to use
    inheritance (virtual) with the templated operator() of 'router'.

    Correct me if I am wrong; I am supposed to write:
    class router {
    public:
    template<class _ITER>
    std::stack<std::iterator_traits<_ITER>::value_type> operator()(_ITER
    _begin, _ITER _end);
    };

    If yes, then what if I what inheritance as well? Routing policies must
    around 4-5 and I was planing to create a router abstract base class
    with some subclasses to implement the actual policies.

    Many thanks,
    -- George
     
    George Exarchakos, Feb 12, 2007
    #7
    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. Brian
    Replies:
    2
    Views:
    338
    Brian
    Oct 31, 2003
  2. Marcin Kaliciñski

    Iterators and reverse iterators

    Marcin Kaliciñski, May 8, 2005, in forum: C++
    Replies:
    1
    Views:
    499
    Kai-Uwe Bux
    May 8, 2005
  3. Protoman
    Replies:
    11
    Views:
    542
  4. 7stud
    Replies:
    11
    Views:
    717
    Dennis Lee Bieber
    Mar 20, 2007
  5. , India
    Replies:
    10
    Views:
    1,096
    James Kanze
    Aug 8, 2009
Loading...

Share This Page