我无法在此课程中获得“打印”功能以获得正确的总数
class PRN {
private:
typedef pair < string, int > P;
int sz, // map size – no of distinct words
cnt, // counter for printing
total; // no of words
public:
// constructor
PRN ( const int& s = 1, const int& c = 0, const int& t = 0 ){
cnt= c;
total = t;
sz = s;
}
void operator ( ) ( const P& p ){
total += p.second;
cout << total;
}// overloaded operator, where P is defined as
// typedef pair < string, int > P;
void print () const{
cout <<"no of words in output list : " << total << endl;
}
};
然后在我的主要电话中
PRN p (m.size());
for_each(m.begin(),m.end(),p);
p.print();
m是包含一些值的字符串(string,int); 操作员正在添加,因为我正在打印它们,我可以看到它们正在添加但是当我调用p.print()时它返回“总计”为零。
有什么建议吗? 感谢
答案 0 :(得分:2)
问题在于for_each
的行为 - 标准并不保证for_each
在内部工作时不会在内部复制p
。因此,具有状态的类似功能的对象通常不能很好地与标准库函数一起工作。就个人而言,我一直认为这种行为很奇怪,并且破坏了很多具有类似功能的对象,但这就是我们已经处理过的手。
根据您使用它的方式,您可以通过total
成为PRN
的静态成员来获得您想要的行为或多或少的行为,以便所有total
个对象使用的任何地方只有一个PRN
值。缺点是下一个for_each
会从您离开的位置开始,而不是从头开始,但您可以通过执行PRN
构造函数重置total
等操作来缓解这种情况。为零(假设PRN
个物体的寿命很长并且非常靠近它们的使用位置。
另一种可能性是让PRN
个对象包含指向实际包含总数的另一个对象的指针,如下所示:
class PRN
{
private:
struct Storage
{
int total;
};
Storage *s;
public:
PRN():
s(new Storage)
{
}
~PRN()
{
delete s;
}
void operator()(const P& p)
{
s->total += p.second;
...
}
...
};
使用此方法,for_each
复制p
并不重要,因为副本将指向与原始文件相同的存储对象。