我需要复制std::set
到std::vector
:
std::set <double> input;
input.insert(5);
input.insert(6);
std::vector <double> output;
std::copy(input.begin(), input.end(), output.begin()); //Error: Vector iterator not dereferencable
问题出在哪里?
您需要使用back_inserter
:
std::copy(input.begin(), input.end(), std::back_inserter(output));
std::copy
不会将元素添加到您要插入的容器中:它不能;它只有一个进入容器的迭代器。因此,如果将输出迭代器直接传递给std::copy
,则必须确保它指向的范围至少足以容纳输入范围。
std::back_inserter
创建一个输出迭代器,它为每个元素调用push_back
一个容器,因此每个元素都插入到容器中。或者,您可以在 中创建足够数量的元素std::vector
来保存要复制的范围:
std::vector<double> output(input.size());
std::copy(input.begin(), input.end(), output.begin());
或者,您可以使用std::vector
范围构造函数:
std::vector<double> output(input.begin(), input.end());
只需使用带有迭代器的向量的构造函数:
std::set<T> s;
//...
std::vector v( s.begin(), s.end() );
假设您只想要 v 中 s 的内容,并且在将数据复制到 v 之前,v 中没有任何内容。
这是另一种使用方法vector::assign
:
theVector.assign(theSet.begin(), theSet.end());
您没有在矢量对象中保留足够的空间来保存集合的内容。
std::vector<double> output(input.size());
std::copy(input.begin(), input.end(), output.begin());
我认为最有效的方法是预先分配然后放置元素:
template <typename T>
std::vector<T> VectorFromSet(const std::set<T>& from)
{
std::vector<T> to;
to.reserve(from.size());
for (auto const& value : from)
to.emplace_back(value);
return to;
}
这样,我们只会为每个元素调用复制构造函数,而不是先调用默认构造函数,然后再为上面列出的其他解决方案复制赋值运算符。更多说明如下。
可以使用back_inserter ,但它会在向量上调用 push_back() ( https://en.cppreference.com/w/cpp/iterator/back_insert_iterator )。 emplace_back()更有效,因为它避免在使用push_back()时创建临时。这对于普通构造的类型不是问题,但对于非普通构造的类型(例如std::string)会产生性能影响。
我们需要避免使用 size 参数构造一个向量,这会导致所有元素都默认构造(什么都不做)。例如,与使用std::copy()的解决方案一样。
最后,vector::assign()方法或采用迭代器范围的构造函数不是好的选择,因为它们会在集合迭代器上调用 std::distance() (以了解元素的数量) 。这将导致对所有集合元素进行不必要的额外迭代,因为集合是二叉搜索树数据结构,并且它不实现随机访问迭代器。
希望有帮助。
std::copy
不能用于插入空容器。为此,您需要像这样使用 insert_iterator:
std::set<double> input;
input.insert(5);
input.insert(6);
std::vector<double> output;
std::copy(input.begin(), input.end(), inserter(output, output.begin()));
set<T> s;
// some code
vector<T> v;
v.assign(s.begin(), s.end());
COPY 函数将一个迭代器返回到目标范围的末尾(它指向复制的最后一个元素之后的元素)。
反向插入迭代器是一种特殊类型的输出迭代器,旨在允许通常覆盖元素(例如复制)的算法在容器末尾自动插入新元素。
设置操作系统;向量向量;
复制(os.begin(),os.end(),back_inserter(vec));