1

我无法在此类中使用“打印”功能来获得正确的总数

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 是一个包含一些值的映射(字符串,整数);操作员正在添加,因为我正在打印它们,我可以看到它们正在被添加,但是当我调用 p.print() 时,它为“总数”返回零。

有什么建议么?谢谢

4

1 回答 1

2

问题在于for_each- 标准不保证在工作for_each时不会p在内部复制。因此,像这样具有状态的类函数对象通常不能很好地与标准库函数一起使用。就个人而言,我一直认为这种行为很奇怪,并且破坏了拥有类似函数的对象的很多意义,但这就是我们遇到的问题。

根据您使用它的方式,您可以通过创建total的静态成员或多或少地获得所需的行为,以便所有对象使用的任何地方都PRN只有一个值。一个缺点是下一个会从你离开的地方开始,而不是从头开始,但你可以通过将构造函数重置为零来缓解这种情况(假设对象不会存活很长时间并且创建的位置非常接近它们的使用位置)。totalPRNfor_eachPRNtotalPRN

另一种可能性是让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,因为副本将指向与原始对象相同的 Storage 对象。

于 2013-10-02T03:55:03.290 回答