我使用基于范围的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
这些是我用来解析和迭代文件的类,任何想法为什么每次迭代都会调用析构函数? (除此之外,它产生正确的输出)。
答案 0 :(得分:2)
根据C ++标准的6.5.4节,您的编译器不应该这样做。相反,它应该将结束迭代器缓存在一个不可命名的本地。
你的operator!=
是否制作了迭代器的副本(偶然传递值)?
答案 1 :(得分:0)
您每次都会制作本地记录副本。尝试自动&amp;
答案 2 :(得分:0)
我不是C ++专家,但我可以证明我在这里登陆是因为我遇到了海报所描述的相同问题,在阅读了Neil Kirk的评论之后,通过添加“&amp;”来解决问题。在'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;
}
}