Can a functor save values ​​when passed to std :: for_each?

According to the first answer to this question , the functor below should be able to save the value after passing to foreach(I could not get struct Accumulatorin the compilation example, so I built a class).

class Accumulator
{
    public:
        Accumulator(): counter(0){}
        int counter;
        void operator()(const Card & c) { counter += i; }
};

Usage example (in accordance with the example)

// Using a functor
Accumulator acc;
std::for_each(_cards.begin(), _cards.end(), acc);
// according to the example - acc.counter contains the sum of all
// elements of the deque 

std::cout << acc.counter << std::endl;

_cardsimplemented as std::deque<Card>. No matter how long it _cardstakes, it acc.counteris zero after completion for_each. However, when I enter the debugger, I can see the increment counter, since this is due to what accis passed by value?

+3
source share
3 answers

> .

, ( ) std::for_each . , , , for_each.

std::accumulate:

int counter = std::accumulate(_cards.begin(), _cards.end(), 0);

for_each .


( , ), , , count_if:

// unary_function lives in <functional>
struct is_face_up : std::unary_function<const Card&, const bool>
{
    const bool operator()(const card& pC) const
    {
        return pC.isFaceUp(); // obviously I'm guessing
    }
};

int faceUp = std::count_if(_cards.begin(), _cards.end(), is_face_up());
int faceDown = 52 - faceUp;

++ 0x ( ):

int faceUp = std::count_if(_cards.begin(), _cards.end(),
                            [](const Card& pC){ return pC.isFaceUp(); });

.

+6

, , acc .

:

class Accumulator
{
    public:
        Accumulator(): counter(new int(0)){}
        boost::shared_ptr<int> counter;
        void operator()(int i) { *counter += i; }

        int value() { return *counter; }
};
+3

, std:: for_each() ( ). , , .

, std:: for_each() , .

. , . std:: accumulate().
, , for_each() - , , , .

#include <iostream>
#include <algorithm>
#include <vector>

class Card{ public: int i;};
class Accumulator
{
    public:
        Accumulator(): counter(0){}
        int counter;
        void operator()(const Card & c) { counter += c.i; }
};


int main()
{
    std::vector<Card>   cards;

    Accumulator a = std::for_each(cards.begin(), cards.end(), Accumulator());

    std::cout << a.counter << std::endl;

}

Accumalator , .

#include <iostream>
#include <algorithm>
#include <vector>

class Card{ public: int i;};
class Accumulator
{
        int&  counter;
    public:
        // Pass a reference to constructor.
        // Copy construction will pass this correctly into the internal object used by for_each
        Accumulator(int& counterRef): counter(counterRef){}
        void operator()(const Card & c) { counter += c.i; }
};


int main()
{
    std::vector<Card>   cards;

    int counter = 0;  // Count stored here.

    std::for_each(cards.begin(), cards.end(), Accumulator(counter));

    std::cout << counter << std::endl;

}
+3

Source: https://habr.com/ru/post/1729243/


All Articles