473,508 Members | 2,457 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

STL iterator/reverse_iterator

My question is regaring STL iterator/reverse_iterator.

I would like to write a function which does the following

int CFoo::calculate(std::vector<int>::iterator itBegin,
std::vector<int>::iterator itEnd)
{
int nWSum = 0;
std::vector<int>::iterator it = itBegin;
for (int i = 1; it != itEnd; ++it, ++i)
{
nWSum += i*(*it);
}

return nWSum;
}

Ideally, I would like to pass in the forward iterator or the reverse
iterator for the vector (the weighted sum will be different for each).

int nSum1 = oCFoo.calculate(vecA.begin(), vecA.end());
int nSum2 = oCFoo.calculate(vecA.rbegin(), vecA.rend());

How should I setup the interface for calculate so that I can do that?

Thanks.
Jan 25 '06 #1
13 2489
jason schrieb:
My question is regaring STL iterator/reverse_iterator.

I would like to write a function which does the following

int CFoo::calculate(std::vector<int>::iterator itBegin,
std::vector<int>::iterator itEnd)
{
int nWSum = 0;
std::vector<int>::iterator it = itBegin;
for (int i = 1; it != itEnd; ++it, ++i)
{
nWSum += i*(*it);
}

return nWSum;
}


template <class InputIterator>
int CFoo::for_each(InputIterator first, InputIterator last)
{
int nWSum = 0;
InputIterator it = first;
for (int i = 1; it != last; ++it, ++i)
{
nWSum += i*(*it);
}

return nWSum;
}
Jan 26 '06 #2
jason wrote:
My question is regaring STL iterator/reverse_iterator.
How should I setup the interface for calculate so that I can do that?


// "reverse_iterator" is a different type than "iterator". Use a
// template parameter, and as a bonus, it'll now work for
// more than just vectors. ("int" might not be the best to
// use for a return type though...)

template<class T>
int calculate(T itBegin,T itEnd)
{
int nWSum = 0;
T it = itBegin;
for (typename iterator_traits<T>::difference_type i = 1;
it != itEnd; ++it, ++i)
{
nWSum += i*(*it);
}

return nWSum;
}

Jan 26 '06 #3
Greg Buchholz wrote:
jason wrote:
My question is regaring STL iterator/reverse_iterator.
How should I setup the interface for calculate so that I can do that?

// "reverse_iterator" is a different type than "iterator". Use a
// template parameter, and as a bonus, it'll now work for
// more than just vectors. ("int" might not be the best to
// use for a return type though...)

template<class T>
int calculate(T itBegin,T itEnd)
{
int nWSum = 0;
T it = itBegin;
for (typename iterator_traits<T>::difference_type i = 1;
it != itEnd; ++it, ++i)
{
nWSum += i*(*it);
}

return nWSum;
}

I guess it should be:

template <typename T>
int calculate( const T& itBegin, const T& itEnd)

for non-trivial iterator types.

--
Ian Collins.
Jan 26 '06 #4
Ian Collins wrote:
Greg Buchholz wrote:
jason wrote:
My question is regaring STL iterator/reverse_iterator.
How should I setup the interface for calculate so that I can do that?

// "reverse_iterator" is a different type than "iterator". Use a
// template parameter, and as a bonus, it'll now work for
// more than just vectors. ("int" might not be the best to
// use for a return type though...)

template<class T>
int calculate(T itBegin,T itEnd)
{
int nWSum = 0;
T it = itBegin;
for (typename iterator_traits<T>::difference_type i = 1;
it != itEnd; ++it, ++i)
{
nWSum += i*(*it);
}

return nWSum;
}

I guess it should be:

template <typename T>
int calculate( const T& itBegin, const T& itEnd)

for non-trivial iterator types.


How do you increment the iterator? it++ will fail!

Consider

void f(const int& i)
{
++i; // bad: i references a *CONST* int.
}

Similarly,

void f(const std::vector<int>::iterator & it)
{
++it; // bad: it references a const iterator (not a const_iterator).
}
Jan 26 '06 #5
red floyd wrote:
Ian Collins wrote:
Greg Buchholz wrote:
jason wrote:

My question is regaring STL iterator/reverse_iterator.
How should I setup the interface for calculate so that I can do that?

// "reverse_iterator" is a different type than "iterator". Use a
// template parameter, and as a bonus, it'll now work for
// more than just vectors. ("int" might not be the best to
// use for a return type though...)

template<class T>
int calculate(T itBegin,T itEnd)
{
int nWSum = 0;
T it = itBegin;
for (typename iterator_traits<T>::difference_type i = 1;
it != itEnd; ++it, ++i)
{
nWSum += i*(*it);
}

return nWSum;
}

I guess it should be:

template <typename T>
int calculate( const T& itBegin, const T& itEnd)

for non-trivial iterator types.


How do you increment the iterator? it++ will fail!

Consider

void f(const int& i)
{
++i; // bad: i references a *CONST* int.
}

Similarly,

void f(const std::vector<int>::iterator & it)
{
++it; // bad: it references a const iterator (not a const_iterator).
}

No, it is a local:

T it = itBegin;

--
Ian Collins.
Jan 26 '06 #6
Ian Collins wrote:
red floyd wrote:
Ian Collins wrote: [redacted]

I guess it should be:

template <typename T>
int calculate( const T& itBegin, const T& itEnd)

for non-trivial iterator types.


How do you increment the iterator? it++ will fail!

Consider

void f(const int& i)
{
++i; // bad: i references a *CONST* int.
}

Similarly,

void f(const std::vector<int>::iterator & it)
{
++it; // bad: it references a const iterator (not a const_iterator).
}

No, it is a local:

T it = itBegin;


At which point you have the same overhead as if you had passed it by
value. What's the point?
Jan 26 '06 #7
red floyd wrote:
>
I guess it should be:

template <typename T>
int calculate( const T& itBegin, const T& itEnd)

for non-trivial iterator types.
How do you increment the iterator? it++ will fail!

Consider

void f(const int& i)
{
++i; // bad: i references a *CONST* int.
}

Similarly,

void f(const std::vector<int>::iterator & it)
{
++it; // bad: it references a const iterator (not a const_iterator).
}


No, it is a local:

T it = itBegin;


At which point you have the same overhead as if you had passed it by
value. What's the point?


Well, the parameters should be const, any advantage of passing by
reference depends on how complicated the iterator object is. At least
passing be reference only results in one copy, the end iterator is
neither copied or modified.

--
Ian Collins.
Jan 26 '06 #8
Ian Collins wrote:

Well, the parameters should be const, any advantage of passing by
reference depends on how complicated the iterator object is.


Iterators should be small enough that passing by value is appropriate.
All of the algorithms in the standard library do it that way.

--

Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)
Jan 26 '06 #9
Pete Becker wrote:
Ian Collins wrote:

Well, the parameters should be const, any advantage of passing by
reference depends on how complicated the iterator object is.


Iterators should be small enough that passing by value is appropriate.
All of the algorithms in the standard library do it that way.


For tree like data structures, you face an alternative: small iterators
would usually be pointers to nodes. To move in the tree, you need a
parentpointer at each node. Alternatively, you could abandon parent
pointers; but then, iterators would encode a path from the root to the
node. In this case, it is a little more tricky to come up with an
implementation for the iterators that supports fast copy construction and
assignment.

Sometimes you cannot have parent pointers in your tree because different
trees might share nodes: consider for instance that interesting rope thing
that HP/SGI had in their STL implementation.
Best

Kai-Uwe Bux
Jan 26 '06 #10
Kai-Uwe Bux wrote:
Pete Becker wrote:

Ian Collins wrote:
Well, the parameters should be const, any advantage of passing by
reference depends on how complicated the iterator object is.


Iterators should be small enough that passing by value is appropriate.
All of the algorithms in the standard library do it that way.

For tree like data structures, you face an alternative: small iterators
would usually be pointers to nodes. To move in the tree, you need a
parentpointer at each node. Alternatively, you could abandon parent
pointers; but then, iterators would encode a path from the root to the
node. In this case, it is a little more tricky to come up with an
implementation for the iterators that supports fast copy construction and
assignment.

Sometimes you cannot have parent pointers in your tree because different
trees might share nodes: consider for instance that interesting rope thing
that HP/SGI had in their STL implementation.


Nevertheless, STL passes iterators by value. If you have specialized
iterators that can't be passed efficiently by value you cannot use them
with standard algorithms.

--

Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)
Jan 26 '06 #11
In article <D2***************@fe05.lga>,
"jason" <ja***********@charter.net> wrote:
My question is regaring STL iterator/reverse_iterator.

I would like to write a function which does the following

int CFoo::calculate(std::vector<int>::iterator itBegin,
std::vector<int>::iterator itEnd)
{
int nWSum = 0;
std::vector<int>::iterator it = itBegin;
for (int i = 1; it != itEnd; ++it, ++i)
{
nWSum += i*(*it);
}

return nWSum;
}

Ideally, I would like to pass in the forward iterator or the reverse
iterator for the vector (the weighted sum will be different for each).

int nSum1 = oCFoo.calculate(vecA.begin(), vecA.end());
int nSum2 = oCFoo.calculate(vecA.rbegin(), vecA.rend());

How should I setup the interface for calculate so that I can do that?


Do it like the standard library does it.

template < typename T >
typename T::value_type calc2( T begin, T end ) {
typename T::value_type result = 0;
int i = 1;
while ( begin != end )
result += i++ * (*begin++);
return result;
}

The above has the added bonus of being usable with any container type
(const or non-const) and any value type (that can handle '+=' and '*').

Now let's have some fun! Why re-invent the loop?

template < typename T >
class weighted_sum {
T _result;
int _count;
public:
weighted_sum():_result( 0 ), _count( 1 ) { }
T operator()( T i ) {
_result += _count++ * i;
return _result;
}
T result() const { return _result; }
};
The above can be used thusly:

vector<int> test;
// ...
int forward_result =
for_each( test.begin(), test.end(), weighted_sum<int>() ).result() );

Or we can be *really* clever!

vector< int > results;
transform( test.begin(), test.end(), back_inserter(results),
weighted_sum<int>() );
--
Magic depends on tradition and belief. It does not welcome observation,
nor does it profit by experiment. On the other hand, science is based
on experience; it is open to correction by observation and experiment.
Jan 27 '06 #12
Pete Becker wrote:
Ian Collins wrote:

Well, the parameters should be const, any advantage of passing by
reference depends on how complicated the iterator object is.


Iterators should be small enough that passing by value is appropriate.
All of the algorithms in the standard library do it that way.

Which make the use of const irrelevant. I'll go away now....

--
Ian Collins.
Jan 27 '06 #13
In article <11***************@drone2-svc-skyt.qsi.net.nz>,
Ian Collins <ia******@hotmail.com> wrote:
Pete Becker wrote:
Ian Collins wrote:

Well, the parameters should be const, any advantage of passing by
reference depends on how complicated the iterator object is.


Iterators should be small enough that passing by value is appropriate.
All of the algorithms in the standard library do it that way.

Which make the use of const irrelevant. I'll go away now....


Since you have to copy the first iterator, passing it in by const ref
doesn't help you at all, better would be to pass by value and not bother
making a copy. I could see accepting the end iterator by const ref
though... Call this a compromise between the two of you. :-)
Jan 27 '06 #14

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
2163
by: Martin Magnusson | last post by:
Hi I'm traversing a std::list backwards with a reverse_iterator, and need to check for the case when the iterator points to the first element of the list. My code now looks something like the...
8
4249
by: Alexander Stippler | last post by:
Hello, the standard requires a type reverse_iterator. But in the form it is required and implemented for all compilers I know, there is IMO something missing, which is essential for its usage....
5
1815
by: AlesD | last post by:
Hello, could you please help me with following problem: I have reversible container which holds (unsorted) instances of objects with common base class. From time to time I need to search for...
29
3937
by: Hagen | last post by:
Hello, in a recent thread "speed of vector vs array" I read about the problem of the slow acces by addressing vector elements by indexing, unfortunately I see no workaround in my case. My...
0
1937
by: nick | last post by:
Hi, I need to manage a "layered" collection of objects, where each layer grows independently, e.g, o--+--+--+--+--+ 1st layer | o 2nd layer (empty) | o--+--+--+ 3rd...
4
1814
by: KL | last post by:
Well, I got through those other hurdles, but now I am stuck with trying to get an iterator to work. I am having a problem with trying to iterate through the STL list container that I set up. I...
3
6081
by: Dalbosco J-F | last post by:
Hi, Sorry if this has already been answered. Given a std::list and a reverse_iterator is there a way to erase the element pointed to by the reverse_iterator via the erase method? Apparently...
15
25419
by: Boltar | last post by:
Hi I'm going through an STL list container using a reverse iterator but it seems the erase() method only accepts ordinary iterators. Is there a similar method that will accept reverse iterators...
3
2881
by: bb | last post by:
Hi, Please could you clarify why 'implicit conversion' does not take place while assigning an iterator to reverse_iterator. However, it happens while initializing/constructing. e.g. typedef...
0
7224
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
7118
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
7379
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
1
7038
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
5625
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
1
5049
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
4706
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
1
763
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
415
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.