C++ 当传递给std::for_时,函子能否保留每个值?

C++ 当传递给std::for_时,函子能否保留每个值?,c++,functor,C++,Functor,根据问题的第一个答案,下面的函子在传递给foreach后应该能够保留一个值(我无法编译示例中的结构累加器,因此构建了一个类) 示例用法(根据示例) //使用函子 蓄能器acc; std::for_each(_cards.begin(),_cards.end(),acc); //根据示例-acc.计数器包含所有 //德克元素 std::cout是的,它肯定与通过值传递的acc有关 按如下方式修改累加器: class Accumulator { public: Accumul

根据问题的第一个答案,下面的函子在传递给
foreach
后应该能够保留一个值(我无法编译示例中的
结构累加器,因此构建了一个类)

示例用法(根据示例)

//使用函子
蓄能器acc;
std::for_each(_cards.begin(),_cards.end(),acc);
//根据示例-acc.计数器包含所有
//德克元素

std::cout是的,它肯定与通过值传递的acc有关

按如下方式修改累加器:

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

        int value() { return *counter; }
};
类累加器
{
公众:
累加器():计数器(新整数(0)){}
boost::共享的ptr计数器;
void运算符()(int i){*计数器+=i;}
int value(){return*counter;}
};
这只是一个例子

原因是(正如您所猜测的)
std::for_每个
复制它的函子,并调用它。但是,它也会返回它,如上面链接的答案中所述,为每个
使用
的返回值

也就是说,您只需要使用:

函子和每个
在这里不正确


对于您的使用(计算一些,忽略其他),您可能需要提供自己的functor并使用:


更好。

这是因为std::for_each()在内部创建了函子的副本(因为传递临时对象是可以的)。因此,它在内部对副本进行求和,而不是对您提供的对象进行求和

好消息是std::for_each()返回一个函子的副本作为结果,因此您可以从那里访问它

注意:您还可以使用其他标准算法。像std::accumulate()。
但是,假设这只是一个简化的示例,并且您需要使用比示例稍微复杂的东西,有两种技术允许您访问accumulator对象

#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;

}
#包括
#包括
#包括
类别卡{public:int i;};
类累加器
{
公众:
累加器():计数器(0){}
整数计数器;
void运算符()(const Card&c){counter+=c.i;}
};
int main()
{
向量卡;
累加器a=std::for_each(cards.begin()、cards.end()、Accumulator());

std::cout-Ew,堆分配只是为了得到结果?@GMan:是的。我得出的结论是,
std::for_each
几乎是一种反模式——看起来应该有用,但几乎在所有情况下都会出错,使用它会适得其反。@Jerry:有点,我同意。通常需要更多的工作我认为lambdas是最常用的算法之一。@GMan:是的,lambdas在某种程度上是有帮助的,但在另一方面,它们实际上会造成更大的伤害。把lambdas看作是一把锤子。它对螺丝钉不起作用。对lambdas使用
for each
通常相当于使用big足够大的锤子,它可以驱动螺丝(以某种方式)。螺丝刀仍然工作得更好…@GMan:不仅有“针对特定任务的更简单的替代品”,但我甚至可以说几乎所有的任务都有更好的选择。谢谢。现在开心吗?:-)顺便问一下,我上面关于
faceup
facedown
的评论是否仍然否定了每个任务的必要性?我想
std::accumulate
不完全是我想要的。不,这是正确的。但是,计数是正确的您的情况将是一个
std::pair
为每个迭代复制可能有些夸张。它只是按值接受谓词,唯一可考虑的选择是按常量引用接受它-这仍然不允许这种用法(非常量
操作符()
).@UncleBens,是的,调试显示默认的ctor被调用一次(我假设在
累加器acc
声明中),然后一个副本ctor被调用两次-无论
\u cards.size()
。请参考这个问题。这和我用计数器作为简单示例来解释这个概念的问题是一样的。实际上,我想做的是保留值
faceup
facedown
,即迭代
deque
并查询deque中的每张卡,保持正面向上或向下的计数。使用静态变量怎么样在函子中?
class Accumulator
{
    public:
        Accumulator(): counter(new int(0)){}
        boost::shared_ptr<int> counter;
        void operator()(int i) { *counter += i; }

        int value() { return *counter; }
};
int counter = std::accumulate(_cards.begin(), _cards.end(), 0);
// 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;
int faceUp = std::count_if(_cards.begin(), _cards.end(),
                            [](const Card& pC){ return pC.isFaceUp(); });
#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;

}
#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;

}