Connecting Tech Pros Worldwide Forums | Help | Site Map

Function Objects with Iterators

gexarchakos
Guest
 
Posts: n/a
#1: Feb 11 '07
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 _TYPEclass 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<_TYPEoperator()(iterator _begin, iterator _end);
};

template<class _MSG, class _CLKclass 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


John Harrison
Guest
 
Posts: n/a
#2: Feb 11 '07

re: Function Objects with Iterators


gexarchakos wrote:
Quote:
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 _TYPEclass 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<_TYPEoperator()(iterator _begin, iterator _end);
};
>
template<class _MSG, class _CLKclass 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
gexarchakos
Guest
 
Posts: n/a
#3: Feb 11 '07

re: Function Objects with Iterators


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 _ITERstd::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

Alan Johnson
Guest
 
Posts: n/a
#4: Feb 11 '07

re: Function Objects with Iterators


gexarchakos wrote:
Quote:
What if:
class router {
public:
template<class _ITERstd::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
red floyd
Guest
 
Posts: n/a
#5: Feb 12 '07

re: Function Objects with Iterators


John Harrison wrote:
Quote:
gexarchakos wrote:
Quote:
>[redacted]
>template<class _TYPEclass 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<_TYPEoperator()(iterator _begin, iterator _end);
>};
>>
>template<class _MSG, class _CLKclass 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.
George Exarchakos
Guest
 
Posts: n/a
#6: Feb 12 '07

re: Function Objects with Iterators


On Feb 12, 12:47 am, red floyd <no.s...@here.dudewrote:
Quote:
John Harrison wrote:
Quote:
gexarchakos wrote:
Quote:
[redacted]
template<class _TYPEclass 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<_TYPEoperator()(iterator _begin, iterator _end);
};
>
Quote:
Quote:
template<class _MSG, class _CLKclass 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);
};
>
Quote:
Quote:
[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
Guest
 
Posts: n/a
#7: Feb 12 '07

re: Function Objects with Iterators


On Feb 11, 11:35 pm, Alan Johnson <a...@yahoo.comwrote:
Quote:
gexarchakos wrote:
Quote:
What if:
class router {
public:
template<class _ITERstd::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

Closed Thread