2

我正在使用基于范围的 for 循环来使用迭代器读取(和解析)文件。我的循环如下所示:

for (auto record : reader) {
    if (even)
        record.reverse_complement();
    cout << record.write();
    even = !even;
} 

我已将输出添加到迭代器的构造函数和析构函数,看起来析构函数在 for 循环的每次迭代中由 end() 返回的迭代器上被调用。

calling fq_iter FULL constructor 
calling fq_iter default constructor 
calling fq_iter destructor on 0
calling fq_iter destructor on 0
calling fq_iter destructor on 0
calling fq_iter destructor on 0
calling fq_iter destructor on 0
calling fq_iter destructor on 0
calling fq_iter destructor on 0
calling fq_reader destructor on 0

这些是我用来解析和迭代文件的类,知道为什么每次迭代都会调用析构函数吗?(除此之外,它会产生正确的输出)。

4

3 回答 3

5

根据 C++ 标准的第 6.5.4 节,您的编译器不应该这样做。相反,它应该将结束迭代器缓存在一个不可命名的本地。

您是否operator!=制作了迭代器的副本(意外传递值)?

于 2013-07-17T16:35:28.290 回答
1

您每次都在制作本地记录副本。尝试自动&

于 2013-07-17T16:35:56.627 回答
1

我不是 C++ 大师,但我可以证明我来到这里是因为我遇到了与海报描述的相同的问题,并且在阅读了 Neil Kirk 的评论后,通过在 'auto' 关键字后添加一个 '&' 问题消失了:

#include <iostream>
#include <array>

class Foo
{   
     int foo;
public:
    Foo() :foo(0) { std::cout << "Foo()" << std::endl; }
    Foo(int foo_) :foo(foo_) { std::cout << "Foo(int)" << std::endl; }
    virtual ~Foo() { std::cout << "~Foo" << std::endl; }
    int getFoo() { return foo; }
};

int main()
{
    std::array<Foo, 10> mainFoo = {0,11,22,33,44,55,66,77,88,99};

    //No destructors are called in this loop:
    for (auto aiter = mainFoo.begin(); aiter != mainFoo.end(); aiter++)
    {
        std::cout << aiter->getFoo() << std::endl;
    }

    //Destructors are called in this loop without the '&' in 'auto&':
    for (auto& i : mainFoo)
    {
        std::cout << i.getFoo() << std::endl;
    }
}
于 2017-05-29T09:08:11.147 回答