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