473,757 Members | 6,899 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

how to use for_each to collect some info from a vector into anothervector

Hi,
I am not familiar with for_each very well, suppoase I have a
vector<pair<uns igned int, unsigned int> > vec1 and the contents are

{<0x00000000, 0x000000FF>, <0x10000000, 0x2FFFFFFF>}

what I want is to create another vector, vector<int> vec2, which store
all the first 8 bit heads of the integer in vec1, for the above example,

0x00000000 & 0xFF000000 ==> 0x00000000,
0x000000FF & 0xFF000000 ==> 0x00000000,
0x10000000 & 0xFF000000 ==> 0x10000000,
0x2FFFFFFF & 0xFF000000 ==> 0x2F000000,

then vec2 should be {0x00000000, 0x10000000, 0x2F000000}.

It's easy to specifically write a for loop, just wonder how to do it
use for_each.

Thanks.
Jul 22 '05
18 2025
In article <Iz************ *******@bgtnsc0 4-news.ops.worldn et.att.net>,
"Siemel Naran" <Si*********@RE MOVE.att.net> wrote:
"Daniel T." <po********@eat hlink.net> wrote in message
news:po******* *************** ********@news6. west.earthlink. net...
jc*****@taeus.c om (Jerry Coffin) wrote:
>> But we want tyo iterate over vec1[0].first then vec1[0].second then
>> vec1[1].first then vec[1].second. For this we need to write asegmented >> iterator (ie. a double iterator). Then
>>
>> std::transform( OverPair(vec1.b egin()), OverPair(vec1.e nd()),
>> std::back_inser ter(vec2), top8);
>
>That certainly looks a lot better, provided that my reread of the
>requirements isn't wrong (again).


I've been playing around this this for a bit. At this point, I don't
think the requirements can be met using std::transform. There is simply
no way to write "OverPair" to make this work. I'd love to be proven
wrong though...


class OverPair {

[snip]

I almost ignored what you wrote because it didn't compile, but then the
light came on. Thank you... I went ahead and wrote it up as a template
and cleaned it up a bit:

template < typename Iter >
class OverPair:
public iterator<forwar d_iterator_tag,
typename Iter::value_typ e::first_type >
{
bool onFirst;
Iter it;
public:
OverPair( Iter i ): onFirst( true ), it( i ) { }

typename Iter::value_typ e::first_type& operator*() {
if ( onFirst )
return it->first;
return it->second;
}

bool onFirstElem() const { return onFirst; }
const Iter& iter() const { return it; }

OverPair& operator++() {
if ( !onFirst ) {
++it;
}
onFirst = !onFirst;
return *this;
}

OverPair operator++(int) {
OverPair temp( *this );
++*this;
return temp;
}
};

template < typename Iter >
bool operator==( const OverPair<Iter>& lhs, const OverPair<Iter>& rhs ) {
return lhs.onFirstElem () == rhs.onFirstElem () &&
lhs.iter() == rhs.iter();
}

template < typename Iter >
bool operator!=( const OverPair<Iter>& lhs, const OverPair<Iter>& rhs )
{ return !( lhs == rhs ); }

template < typename Iter >
OverPair<Iter> over_pair( Iter it ) {
return OverPair<Iter>( it);
}

Then it would be used like this:

binder2nd< bit_and<unsigne d int> > high_8_mask =
bind2nd( bit_and< unsigned >(), 0xFF000000 );
transform( over_pair(v.beg in()), over_pair(v.end ()),
back_inserter(v 2), high_8_mask );

Of course, one has to wonder whether the STL functional approach is worth
the trouble as opposed to write an explicit for loop. Sometimes it might
be, as when we want to free ourselves from the logic of segemented
iterators, and use many different algorithms.


Well there is also the fact that the origional loop wasn't even remotly
reusable. The above code, on the other hand, can be used to load our
vector<pair<uns igned, unsigned> > from a stream, or write it to a stream
(making testing the values within it much easer.) That's three uses
already and I'm not even trying...
Jul 22 '05 #11
In article <po************ *************** ***@news1.west. earthlink.net>,
"Daniel T." <po********@eat hlink.net> wrote:
In article <Iz************ *******@bgtnsc0 4-news.ops.worldn et.att.net>,
"Siemel Naran" <Si*********@RE MOVE.att.net> wrote:
"Daniel T." <po********@eat hlink.net> wrote in message
news:po****** *************** *********@news6 .west.earthlink .net...
jc*****@taeus.c om (Jerry Coffin) wrote:

>> But we want tyo iterate over vec1[0].first then vec1[0].second then
>> vec1[1].first then vec[1].second. For this we need to write a

segmented
>> iterator (ie. a double iterator). Then
>>
>> std::transform( OverPair(vec1.b egin()), OverPair(vec1.e nd()),
>> std::back_inser ter(vec2), top8);
>
>That certainly looks a lot better, provided that my reread of the
>requirements isn't wrong (again).

I've been playing around this this for a bit. At this point, I don't
think the requirements can be met using std::transform. There is simply
no way to write "OverPair" to make this work. I'd love to be proven
wrong though...


class OverPair {

[snip]

I almost ignored what you wrote because it didn't compile, but then the
light came on. Thank you... I went ahead and wrote it up as a template
and cleaned it up a bit


[snipped code]

I'm normally not one to reply to my own posts, but I've been thinking
about the solutions presented so far:

The basic loop, has absolutly no reuse value but expresses itself
clearly to even the most raw beginner.

for_each and a custom functor, also has little to no reuse value and
removes to locality of reference that the loop has, which makes it
harder to understand.

Segmented iterator, has a slightly higher reuse potential and once you
know how the OverPair iterator works, is easy to understand (although
comming up with it wasn't very intuitave for me.)

expanding_trans form algorithm, has the greatest reuse potential while
requiring a better undersanding of how to compose functors.

I think the basic loop is only easer to understand for beginners because
of the way most books teach C++, starting out as a "better C" and going
up from there. I expect that someone who learned C++ from the library
down rather than from pointers up, would find one of the other solutions
more natural.
Jul 22 '05 #12
"Daniel T." <po********@eat hlink.net> wrote in message news:postmaster-
"Siemel Naran" <Si*********@RE MOVE.att.net> wrote: I almost ignored what you wrote because it didn't compile, but then the
light came on. Thank you... I went ahead and wrote it up as a template
and cleaned it up a bit:
What you have is good, but there were just some minor errors.
class OverPair {
public:
/* the usual 5 typedefs: iterator_catego ry, reference, etc */
The above includes

typedef unsigned& reference;
OverPair(std::v ector<unsigned> ::iterator outer) : d_outer(outer),
d_inner(FIRST) { }
Above line is bullshit. We have a vector of pair<unsigned,u nsigned>. So
change that to

typedef std::pair<unsig ned, unsigned> Pair;
OverPair(std::v ector<Pair>::it erator outer) : d_outer(outer),
d_inner(FIRST) { }
friend bool operator==(cons t OverPair&, const OverPair&) const {
return lhs.d_outer == rhs.d_outer && lhs.d_inner == rhs.d_inner;
}
Mistake above is to make member function const. Remove the const. Also
name the variables lhs and rhs.

friend bool operator==(cons t OverPair& lhs, const OverPair& rhs) {
return lhs.d_outer == rhs.d_outer && lhs.d_inner == rhs.d_inner;
}
reference operator*() {
Pair& pair = *d_outer;
switch (d_inner) {
case FIRST: return pair.first;
case SECOND: return pair.second;
}
return Pair();
}
Compiler gives me error that last line should return a lvalue. Of course,
this line is never reached. So change to

reference operator*() {
Pair& pair = *d_outer;
if (d_inner == FIRST) return pair.first;
return pair.second;
}

OverPair operator++() {
++d_inner;
Compiler complains for the above line. Either overload operator++ for the
enum or use

d_inner = Element(d_inner +1);

if (d_inner > SECOND) {
d_inner = FIRST;
++d_outer;
}
return *this;
} private:
typedef std::pair<unsig ned, unsigned> Pair;
Remove the above line as we added it earlier.
enum Element { FIRST, SECOND };
std::vector<Pai r>::iterator d_outer;
Element d_inner;
}; template < typename Iter >
class OverPair:
public iterator<forwar d_iterator_tag,
typename Iter::value_typ e::first_type >
{
bool onFirst;
Iter it;
public:
OverPair( Iter i ): onFirst( true ), it( i ) { }

typename Iter::value_typ e::first_type& operator*() {
if ( onFirst )
return it->first;
return it->second;
}

bool onFirstElem() const { return onFirst; }
const Iter& iter() const { return it; }

OverPair& operator++() {
if ( !onFirst ) {
++it;
}
onFirst = !onFirst;
return *this;
}

OverPair operator++(int) {
OverPair temp( *this );
++*this;
return temp;
}
};

template < typename Iter >
bool operator==( const OverPair<Iter>& lhs, const OverPair<Iter>& rhs ) {
return lhs.onFirstElem () == rhs.onFirstElem () &&
lhs.iter() == rhs.iter();
}

template < typename Iter >
bool operator!=( const OverPair<Iter>& lhs, const OverPair<Iter>& rhs )
{ return !( lhs == rhs ); }

template < typename Iter >
OverPair<Iter> over_pair( Iter it ) {
return OverPair<Iter>( it);
}

Then it would be used like this:

binder2nd< bit_and<unsigne d int> > high_8_mask =
bind2nd( bit_and< unsigned >(), 0xFF000000 );
transform( over_pair(v.beg in()), over_pair(v.end ()),
back_inserter(v 2), high_8_mask );


Yes, it's essentially the same concept.

Of course, one has to wonder whether the STL functional approach is worth
the trouble as opposed to write an explicit for loop. Sometimes it might
be, as when we want to free ourselves from the logic of segemented
iterators, and use many different algorithms.


Well there is also the fact that the origional loop wasn't even remotly
reusable. The above code, on the other hand, can be used to load our
vector<pair<uns igned, unsigned> > from a stream, or write it to a stream
(making testing the values within it much easer.) That's three uses
already and I'm not even trying...


But is it worth the trouble to write such a complex iterator class? It
certainly could be, but I'm not totally convinced as yet. Just keeping an
open mind.
Jul 22 '05 #13
"Daniel T." <po********@eat hlink.net> wrote in message news:postmaster-
The basic loop, has absolutly no reuse value but expresses itself
clearly to even the most raw beginner.
Which one was the basic loop?
for_each and a custom functor, also has little to no reuse value and
removes to locality of reference that the loop has, which makes it
harder to understand.
Yes, that's the trouble I have with for_each. Though if you can use
existing binders and functors like std::equal and the ones in boost, you can
make the intent clear in the calling code. But on the other hand, there's a
high learning curve to understanding these functors. Sure, std::equal makes
sense as does std::bind2nd, but throw them together and the resulting code
looks a tad intimidating. Also, there's a proposal to enhance the C++
standard to allow local classes to have an external linkage. This would
allow us to define the class inside the function that uses it in a call to
for_each. This could be a nice boost (sorry for the bad pun :) to the use
of for_each, transform, and the others.
Segmented iterator, has a slightly higher reuse potential and once you
know how the OverPair iterator works, is easy to understand (although
comming up with it wasn't very intuitave for me.)
Sure, the segmented iterator is a challenge, but now you know how to write a
std::deque::ite rator.
expanding_trans form algorithm, has the greatest reuse potential while
requiring a better undersanding of how to compose functors.


What is expanding_trans form?

Jul 22 '05 #14
In article <gp************ ******@bgtnsc04-news.ops.worldn et.att.net>,
"Siemel Naran" <Si*********@RE MOVE.att.net> wrote:
"Daniel T." <po********@eat hlink.net> wrote in message news:postmaster-
The basic loop, has absolutly no reuse value but expresses itself
clearly to even the most raw beginner.


Which one was the basic loop?


for ( vector< pair< unsigned, unsigned > >::iterator it = v.begin();
it != v.end(); ++it )
{
v2.push_back( it->first & 0xFF000000 );
v2.push_back( it->second & 0xFF000000 );
}
for_each and a custom functor, also has little to no reuse value and
removes to locality of reference that the loop has, which makes it
harder to understand.


Yes, that's the trouble I have with for_each. Though if you can use
existing binders and functors like std::equal and the ones in boost, you can
make the intent clear in the calling code. But on the other hand, there's a
high learning curve to understanding these functors. Sure, std::equal makes
sense as does std::bind2nd, but throw them together and the resulting code
looks a tad intimidating.


Only because we were taught C++ "from the ground up". First as a "better
C", with the libraries coming last. I suspect that someone who was
taught C++ from the libraries down (much like in the book "Accelerate d
C++" this would be much less of an issue.

IMO, proper use of the standard library (especially the algorithms and
functors) is what makes someone a C++ programmer, rather than a
programmer who happens to use C++.

expanding_trans form algorithm, has the greatest reuse potential while
requiring a better understanding of how to compose functors.


What is expanding_trans form?


That was my solution to the problem presented:

Write a new algorithm:

template < typename InputIter, typename OutputIter,
typename Op1, typename Op2 >
OutputIter expanding_trans form( InputIter first, InputIter last,
OutputIter result, Op1 op1, Op2 op2 )
{
while ( first != last )
{
*result++ = op1( *first );
*result++ = op2( *first );
++first;
}
return result;
}

Then use a couple of functors that came in STL (but didn't make it into
the standard) to produce:

typedef pair< unsigned, unsigned > two_flags;

binder2nd< bit_and< unsigned > > high_8_mask =
bind2nd( bit_and< unsigned >(), 0xFF000000 );

expanding_trans form( v.begin(), v.end(), back_inserter( v2 ),
compose1( high_8_mask, select1st< two_flags >() ),
compose1( high_8_mask, select2nd< two_flags >() ) );

expanding_trans form has more reuse potential than OverPair because it
can be used on input that *isn't* a pair.
Jul 22 '05 #15
"Daniel T." <po********@eat hlink.net> wrote:
(Jerry Coffin) wrote:

[snip lots of complicated crap]
Arrogant prediction: nobody will post a better solution using
for_each. :-)


Much too arrogant. Your code fails to do what the OP wanted done. Try
again. But I mean this. Please try again because I couldn't figure out a
solution without writing a new algorithm and I'd love to see if it can
be done using transform.


#include <algorithm>
#include <utility>
#include <vector>

typedef std::pair<unsig ned int, unsigned int> upair;

unsigned int head(upair p1, upair p2)
{ return p1.first & p2.second & 0xFF000000; }

// ...
std::vector< upair > vec;
// ...

std::vector< uint > out(vec.size()) ;
std::transform( vec.begin(), vec.end(), vec.begin(), out.begin(), head);
Jul 22 '05 #16
In article <84************ **************@ posting.google. com>,
ol*****@inspire .net.nz (Old Wolf) wrote:
"Daniel T." <po********@eat hlink.net> wrote:
(Jerry Coffin) wrote:

[snip lots of complicated crap]
>Arrogant prediction: nobody will post a better solution using
>for_each. :-)


Much too arrogant. Your code fails to do what the OP wanted done. Try
again. But I mean this. Please try again because I couldn't figure out a
solution without writing a new algorithm and I'd love to see if it can
be done using transform.


#include <algorithm>
#include <utility>
#include <vector>

typedef std::pair<unsig ned int, unsigned int> upair;

unsigned int head(upair p1, upair p2)
{ return p1.first & p2.second & 0xFF000000; }

// ...
std::vector< upair > vec;
// ...

std::vector< uint > out(vec.size()) ;
std::transform( vec.begin(), vec.end(), vec.begin(), out.begin(), head);


Still doesn't work. After the transform is complete, out.size() will
equal vec.size() which is not what the OP wanted. He wanted out.size()
to equal vec.size() * 2.
Jul 22 '05 #17
"Daniel T." <po********@eat hlink.net> wrote:
Old Wolf wrote:
"Daniel T." <po********@eat hlink.net> wrote:
Much too arrogant. Your code fails to do what the OP wanted done. Try
again. But I mean this. Please try again because I couldn't figure out a
solution without writing a new algorithm and I'd love to see if it can
be done using transform.

std::vector< uint > out(vec.size()) ;
std::transform( vec.begin(), vec.end(), vec.begin(), out.begin(), head);


Still doesn't work. After the transform is complete, out.size() will
equal vec.size() which is not what the OP wanted. He wanted out.size()
to equal vec.size() * 2.


Ah. I misread the OP's question (several times..) , his input had
2 pairs and 3 outputs (so I guess 2 outputs was as good a guess as 4 :)
In that case, I think std::transform is not appropriate, as the output
list has to be the same size as the input list. I'd stick with for_each.

OTOH, I wonder if he did that on purpose and wants his output vector
to not repeat duplicates..
Jul 22 '05 #18
In article <84************ **************@ posting.google. com>,
ol*****@inspire .net.nz (Old Wolf) wrote:
"Daniel T." <po********@eat hlink.net> wrote:
Old Wolf wrote:
>"Daniel T." <po********@eat hlink.net> wrote:
>> Much too arrogant. Your code fails to do what the OP wanted done. Try
>> again. But I mean this. Please try again because I couldn't figure out a
>> solution without writing a new algorithm and I'd love to see if it can
>> be done using transform.
> std::vector< uint > out(vec.size()) ;
> std::transform( vec.begin(), vec.end(), vec.begin(), out.begin(), head);


Still doesn't work. After the transform is complete, out.size() will
equal vec.size() which is not what the OP wanted. He wanted out.size()
to equal vec.size() * 2.


Ah. I misread the OP's question (several times..) , his input had
2 pairs and 3 outputs (so I guess 2 outputs was as good a guess as 4 :)
In that case, I think std::transform is not appropriate, as the output
list has to be the same size as the input list. I'd stick with for_each.


As has been shown, it *can* be done with transform as long as you have
an iterator that can handle it. But overall, I agree with you. I think
it better to make a new algorithm for this problem, that can also be
used in other related problems...

OTOH, I wonder if he did that on purpose and wants his output vector
to not repeat duplicates..


The simple solution there is to output into a set first, then copy the
set to the output vector (if necessary.) It becomes much harder if the
items need to be kept in the same order though. In that case, one would
be forced to use a custom iterator that keeps track internaly what items
have been added to the output (ie the iterator would contain a set
object.)
Jul 22 '05 #19

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

Similar topics

5
4678
by: Alex Vinokur | last post by:
Functor-parameters in the for_each() and transform() algorithms are passed by value. Might it make sense to have also algorithms for_each2() and transform2() which pass Functor-parameters by non-const reference? Here is some program which demonstrates probable necessity in such forms of for_each() and transform().
2
1764
by: Eric Lilja | last post by:
Hello, I have a std::vector storing pointers to objects that are dynamically allocated. When I am done with the vector I want to delete all pointers. Can I use std::for_each() or something to do that in one line? I am so tired of seeing the following in my code: for(vector<some_type>::size_type i = 0; i < myvec.size(); ++i) do_something_with_each_element; / Eric
12
2618
by: sashan | last post by:
Sometimes I write code using std::for_each. Sometimes I use it on several container classes that are the same size. for_each(v.begin(), v.end(), f1()); for_each(u.begin(), u.end(), f2()); This seems inefficient so I rewrite it as: int n = v.size(); for (int i = 0; i < n; ++i)
9
1846
by: shaun | last post by:
I am working on code where I am handed a vector of pointers vector<T*> or a map<std::string, T*>, and I have to delete the objects and set the pointers to zero. I have been using a 'for' loop and thought it might be instructive to write a 'deletePointer' which can be used in an algorithm or standalone. (code at end of mail) I discovered I could not simply for_each(v.begin(),v.end(),deletePointer);
27
2235
by: Fraser Ross | last post by:
Is it wrong to describe for_each as a modifying algorithm? It is described as one here: http://www.josuttis.com/libbook/algolist.pdf. transform appears to be the algorithm to use for modifying elements in a range. Fraser. Posted Via Usenet.com Premium Usenet Newsgroup Services
3
2886
by: PolkaHead | last post by:
I was wondering if there's a way to traverse a two-dimensional vector (vector of vectors) with a nested for_each call. The code included traverses the "outer" vector with a for_each, than it relies on the PrintFunctor to traverse the "inner" vector with another for_each. Is it possible to nest the second for_each, so I don't have to include a for_each in my function object. Is it possible to do a: for_each(myVec.begin(), myVec.end(),
9
2605
by: Chris Roth | last post by:
I have a vector of vectors: vector< vector<double v; and have initialized it with: v( 5 ); as I know I will have 5 columns of data. At this point, I read text file data into each of the the vectors using push_back. I know that I will be reading in 5000 elements into each vector, so I use reserve: ifstream f( "file.txt" ); if(f.is_open()) {
3
1575
by: Yan | last post by:
Hi, I don't seem to be able to use for_each if it should replace a 'for' loop in a method (constructor in my case) and inside that 'for' loop a class member variable is being accessed. The presence of this member variable prevents me from using a static or global method to be passed as a third parameter to for_each, and mem_fun doesn't seem to work for me either as I am not going to execute a method of an iterator but pass an iterator...
3
1517
by: fgh.vbn.rty | last post by:
I'm having problems setting up the functors to use for_each. Here's an example: class A { public: void getName() { return name; } private: string name; };
0
9489
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, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
1
9885
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 Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9737
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
8737
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, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
7286
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 presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6562
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 then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5172
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
1
3829
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
3
3399
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

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.