Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

A curiosity with a small program

29 views
Skip to first unread message

Doug Mika

unread,
Apr 30, 2015, 1:38:53 PM4/30/15
to
When I ran the following program:
#include<algorithm>
#include<iostream>
#include<vector>
using namespace std;

template<typename T>
struct DisplayElementKeepCount{
int Count;

DisplayElementKeepCount():Count(0){}

void operator()(const T& element){
++Count;
cout<<element<<' ';
}
};

int main(int argc, char** argv) {

//The Program
vector<int> vecIntegers;

for(int nCount=0;nCount<10; ++nCount)
vecIntegers.push_back(nCount);

DisplayElementKeepCount<int> Result;

cout<<"Displaying the vector of integers again"<<endl;
for_each(vecIntegers.begin(),vecIntegers.end(),Result);
cout<<endl<<endl;

cout<<"The Result count this time is: "<<Result.Count<<endl;


return 0;
}

the result of Result.Count is 0!!!, WHY isn't it 10????? Afterall, I call the oprator() 10 times!

Victor Bazarov

unread,
Apr 30, 2015, 1:47:18 PM4/30/15
to
On 4/30/2015 1:38 PM, Doug Mika wrote:
> When I ran the following program:
> #include<algorithm>
> #include<iostream>
> #include<vector>
> using namespace std;
>
> template<typename T>
> struct DisplayElementKeepCount{
> int Count;
>
> DisplayElementKeepCount():Count(0){}
>
> void operator()(const T& element){
> ++Count;
> cout<<element<<' ';
> }
> };
>
> int main(int argc, char** argv) {
>
> //The Program
> vector<int> vecIntegers;
>
> for(int nCount=0;nCount<10; ++nCount)
> vecIntegers.push_back(nCount);
>
> DisplayElementKeepCount<int> Result;
>
> cout<<"Displaying the vector of integers again"<<endl;
> for_each(vecIntegers.begin(),vecIntegers.end(),Result);

Right here the 'Result' is not used directly, but *copied* into the
argument of 'for_each' function. Inside you're incrementing the 'Count'
member of the copy. The outside object is unchanged.

> cout<<endl<<endl;
>
> cout<<"The Result count this time is: "<<Result.Count<<endl;
>
>
> return 0;
> }
>
> the result of Result.Count is 0!!!, WHY isn't it 10????? Afterall, I call the oprator() 10 times!

Yes, but for which object? Display the 'this' pointer in your
'operator()' and compare it to the address of 'Result' variable.

V
--
I do not respond to top-posted replies, please don't ask

Richard

unread,
Apr 30, 2015, 1:49:37 PM4/30/15
to
[Please do not mail me a copy of your followup]

Doug Mika <doug...@gmail.com> spake the secret code
<a7ca7647-b5c0-4d5a...@googlegroups.com> thusly:
The functor is copied around by for_each, so the one it uses is not
the one that you declared locally, it's a copy. This is implied by
the signature of for_each which takes the functor by value. To get
what you want, you have to use a referring wrapper like boost::ref, or
have your functor reference the count held elsewhere:

#include<algorithm>
#include<iostream>
#include<vector>
using namespace std;

template<typename T>
struct DisplayElementKeepCount{
int &Count;

DisplayElementKeepCount(int &Storage):Count(Storage){}

void operator()(const T& element){
++Count;
cout<<element<<' ';
}
};

int main(int argc, char** argv) {

//The Program
vector<int> vecIntegers;

for(int nCount=0;nCount<10; ++nCount)
vecIntegers.push_back(nCount);

int Count = 0;
DisplayElementKeepCount<int> Result(Count);

cout<<"Displaying the vector of integers again"<<endl;
for_each(vecIntegers.begin(),vecIntegers.end(),Result);
cout<<endl<<endl;

cout<<"The Result count this time is: "<<Result.Count<<endl;


return 0;
}

--
"The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline>
The Computer Graphics Museum <http://computergraphicsmuseum.org>
The Terminals Wiki <http://terminals.classiccmp.org>
Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com>

Christian Gollwitzer

unread,
Apr 30, 2015, 2:29:02 PM4/30/15
to
Am 30.04.15 um 19:49 schrieb Richard:
> Doug Mika <doug...@gmail.com> spake the secret code
>>
>> for_each(vecIntegers.begin(),vecIntegers.end(),Result);
>
> The functor is copied around by for_each, so the one it uses is not
> the one that you declared locally, it's a copy. This is implied by
> the signature of for_each which takes the functor by value. To get
> what you want, you have to use a referring wrapper like boost::ref, or
> have your functor reference the count held elsewhere:

...or better yet, forget about for_each - this was just an auxiliary
construct in C++ before 11, to avoid ugly for loops. Nowadays we have

for (auto i: vecIntegers) {
Result(i)
}

which does what you want, is more readable in my opinion and can also be
done without a functor, if the only reason for the functor was for_each
in the end.

Christian

Doug Mika

unread,
Apr 30, 2015, 2:30:01 PM4/30/15
to
I guess one more newbie question:

When this functor is passed by value, I assume it's the entire object (along with implementation of operator()) that is passed by value, and that if I have a copy constructor implemented, it will be used to pass that entire functor by value, correct?

Thanks

Paavo Helde

unread,
Apr 30, 2015, 2:36:57 PM4/30/15
to
Doug Mika <doug...@gmail.com> wrote in
news:a7ca7647-b5c0-4d5a...@googlegroups.com:

> When I ran the following program:
> for_each(vecIntegers.begin(),vecIntegers.end(),Result);
>
> the result of Result.Count is 0!!!, WHY isn't it 10????? Afterall, I
> call the oprator() 10 times!

Change this line to:

Result = for_each(vecIntegers.begin(),vecIntegers.end(),Result);

Victor already explained why your version did not work.

Paavo Helde

unread,
Apr 30, 2015, 2:51:20 PM4/30/15
to
Doug Mika <doug...@gmail.com> wrote in
news:4a059c47-2a06-4dc4...@googlegroups.com:

> I guess one more newbie question:
>
> When this functor is passed by value, I assume it's the entire object
> (along with implementation of operator())

An object does not contain any compiled machine code, so implementations of
any functions or operators are not copied. Also, as the compiled code does
not change during the run, it would be the most silly thing to copy it
around in zillions of exemplars.

> that is passed by value, and
> that if I have a copy constructor implemented, it will be used to pass
> that entire functor by value, correct?

Yes, copy constructor will be used in the process (unless the compiler is
able to optimize it away, but this probably does not happen here).

Richard

unread,
Apr 30, 2015, 3:01:10 PM4/30/15
to
[Please do not mail me a copy of your followup]

Doug Mika <doug...@gmail.com> spake the secret code
<4a059c47-2a06-4dc4...@googlegroups.com> thusly:
Correct. If you don't implement the copy constructor, the compiler
supplies one that does simple member-by-member assignment.

Richard

unread,
Apr 30, 2015, 3:02:34 PM4/30/15
to
[Please do not mail me a copy of your followup]

Paavo Helde <myfir...@osa.pri.ee> spake the secret code
<XnsA48CDBD777CBFm...@216.166.105.131> thusly:

>Doug Mika <doug...@gmail.com> wrote in
>news:a7ca7647-b5c0-4d5a...@googlegroups.com:
>
>> When I ran the following program:
>> for_each(vecIntegers.begin(),vecIntegers.end(),Result);
>>
>> the result of Result.Count is 0!!!, WHY isn't it 10????? Afterall, I
>> call the oprator() 10 times!
>
>Change this line to:
>
>Result = for_each(vecIntegers.begin(),vecIntegers.end(),Result);

Nice! I usually forget about the return value of for_each.
Honestly though, range-based for loops in C++11 I don't expect I'll
be using for_each much, even with lambdas.

Victor Bazarov

unread,
Apr 30, 2015, 3:12:26 PM4/30/15
to
On 4/30/2015 3:01 PM, Richard wrote:
> [Please do not mail me a copy of your followup]
>
> Doug Mika <doug...@gmail.com> spake the secret code
> <4a059c47-2a06-4dc4...@googlegroups.com> thusly:
>
>> I guess one more newbie question:
>>
>> When this functor is passed by value, I assume it's the entire object
>> (along with implementation of operator()) that is passed by value, and
>> that if I have a copy constructor implemented, it will be used to pass
>> that entire functor by value, correct?
>
> Correct. If you don't implement the copy constructor, the compiler
> supplies one that does simple member-by-member assignment.

Nit-pick: ".. that does simple member-by-member copy construction."
0 new messages