我有一种奇怪的行为,这可能是一个初学者的问题:
在类成员函数中,我试图用另一个向量替换给定的向量。
template <typename FITNESS_TYPE>
void BaseManager<FITNESS_TYPE>::replacePopulation (
typename Population<FITNESS_TYPE>::chromosome_container replacementPopulation)
{
_population.getChromosomes().clear();
//This inserts the contents of replacementPopulation into _population.getChromosomes()
for (
typename Population<FITNESS_TYPE>::chromosome_container::iterator
it = replacementPopulation.begin();
it != replacementPopulation.end();
++it)
{
_population.getChromosomes().push_back(*it);
}
//But this does nothing...
std::copy(replacementPopulation.begin(),replacementPopulation.end(), _population.getChromosomes().begin());
for (typename Population<FITNESS_TYPE>::chromosome_container::iterator it = _population.getChromosomes().begin(); it!=_population.getChromosomes().end(); ++it)
{
std::cout << "CHROM: " << **it << std::endl;
}
}
相应的getChromosomes()getter如下:
template <typename FITNESS_TYPE>
class Population : public printable {
public:
typedef typename std::vector<Chromosome::BaseChromosome<FITNESS_TYPE>* > chromosome_container;
typedef typename chromosome_container::const_iterator const_it;
typedef typename chromosome_container::iterator it;
const chromosome_container& getChromosomes() const { return _chromosomes; }
chromosome_container& getChromosomes() { return _chromosomes; }
private:
chromosome_container _chromosomes;
};
我很困惑。为什么副本不像for循环那样工作?
答案 0 :(得分:8)
push_back
调整向量的大小,而写入begin()
以及后面的内容假定空间已经存在。你想要的是这样的:
std::copy(replacementPopulation.begin(),
replacementPopulation.end (),
std::back_inserter(_population.getChromosomes()));
#include <iterator>
获取back_inserter
。
本质上,std::back_inserter
是一个迭代器,每次写入内容时都会执行push_back
。
答案 1 :(得分:4)
copy
要求其输出迭代器是有效范围的起点,至少与输入范围一样大。在你的情况下,它是一个空范围的开始;所以copy
会将它从向量的末尾递增出来,写入超出的内存,并导致未定义的行为。
这里最简单的解决方案就是重新分配矢量
_population.getChromosomes() = replacementPopulation;
如果确实需要附加到向量而不是替换其所有内容,则可以使用插入迭代器:
std::copy(replacementPopulation.begin(), replacementPopulation.end(),
std::back_inserter(_population.getChromosomes()));
答案 2 :(得分:3)
vector
实际上有一个insert
方法,它接受迭代器:
_population.getChromosomes().insert(
_population.getChromosomes().end(),
replacementPopulation.begin(),
replacementPopulation.end());
确保_population.getChromosomes()
已正确调整大小,以便您无法运行。根据两个迭代器之间的距离,如果需要,也只会执行一个reserve()
,因此这将比提出的std::copy()
解决方案更加有效。
或者,如果你真的只是复制矢量:
_population.getChromosomes() = replacementPopulation;
答案 3 :(得分:1)
复制假定目标容器中有复制元素的空间,它将替换它们。您可以使用“back_inserter”创建一个特殊的迭代器,它将插入元素而不是替换,以避免在复制之前调整大小。
std::copy(replacementPopulation.begin(),replacementPopulation.end(), std::back_inserter(_population.getChromosomes()));