我需要将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());
output.insert(output.end(), input.begin(), input.end());
来代替吗? - user2015453output.insert(output.cend(), input.cbegin(), input.cend());
你觉得怎么样?谢谢。 - user2015453input,size()
个空条目组成的数组,然后在此之后添加附加项。我认为你想使用 std::vector<double> output; output.reserve(input.size()); std::copy(...);
。 - Alexis Wilke只需使用接受迭代器的向量构造函数:
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());
output.reserve(input.size())
是不够的。 - Sz.我认为最有效的方法是预分配并插入元素:
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 但它会在 vector 上调用 push_back() (https://en.cppreference.com/w/cpp/iterator/back_insert_iterator)。emplace_back() 更有效率,因为它避免了在使用 push_back() 时创建临时对象。对于平凡构造类型来说这不是问题,但对于非平凡构造类型(例如 std::string)则会影响性能。
我们需要避免使用带有大小参数的构造函数创建 vector,因为这会导致所有元素都被默认构造(没必要)。例如像使用 std::copy() 的解决方案。
最后,vector::assign() 方法或使用迭代器范围的构造函数不是好的选择,因为它们将在 set 迭代器上调用 std::distance() 来知道元素数量。这将导致额外的迭代通过所有 set 元素,因为 set 是二叉搜索树数据结构并且没有实现随机访问迭代器。
back_inserter
的解释。 - Tarick Wellingset<T> s;
// some code
vector<T> v;
v.assign(s.begin(), s.end());
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()));
COPY函数返回一个指向目标范围末尾的迭代器(指向最后一个被复制元素之后的位置)。
back-insert迭代器是一种特殊类型的输出迭代器,旨在允许通常会覆盖元素(如copy)的算法自动将新元素插入到容器的末尾。
set os; vector vec;
copy(os.begin(), os.end(), back_inserter(vec));
assign()
函数:output.assign(input.begin(), input.end());
它的作用是将input
容器中的元素赋值给output
容器。 - Gene Bushuyev