161

我需要复制std::setstd::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

问题出在哪里?

4

8 回答 8

232

您需要使用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()); 
于 2011-02-17T20:32:10.503 回答
138

只需使用带有迭代器的向量的构造函数:

std::set<T> s;

//...

std::vector v( s.begin(), s.end() );

假设您只想要 v 中 s 的内容,并且在将数据复制到 v 之前,v 中没有任何内容。

于 2011-02-17T20:36:00.033 回答
49

这是另一种使用方法vector::assign

theVector.assign(theSet.begin(), theSet.end());
于 2014-05-07T22:05:59.230 回答
26

您没有在矢量对象中保留足够的空间来保存集合的内容。

std::vector<double> output(input.size());
std::copy(input.begin(), input.end(), output.begin());
于 2011-02-17T20:33:24.033 回答
3

我认为最有效的方法是预先分配然后放置元素:

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;
}

这样,我们只会为每个元素调用复制构造函数,而不是先调用默认构造函数,然后再为上面列出的其他解决方案复制赋值运算符。更多说明如下。

  1. 可以使用back_inserter ,但它会在向量上调用 push_back() ( https://en.cppreference.com/w/cpp/iterator/back_insert_iterator )。 emplace_back()更有效,因为它避免在使用push_back()时创建临时。这对于普通构造的类型不是问题,但对于非普通构造的类型(例如std::string)会产生性能影响。

  2. 我们需要避免使用 size 参数构造一个向量,这会导致所有元素都默认构造(什么都不做)。例如,与使用std::copy()的解决方案一样。

  3. 最后,vector::assign()方法或采用迭代器范围的构造函数不是好的选择,因为它们会在集合迭代器上调用 std::distance() (以了解元素的数量) 。这将导致对所有集合元素进行不必要的额外迭代,因为集合是二叉搜索树数据结构,并且它不实现随机访问迭代器。

希望有帮助。

于 2019-06-12T19:09:12.090 回答
1

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())); 
于 2011-02-17T20:34:25.927 回答
1
set<T> s;
// some code
vector<T> v;
v.assign(s.begin(), s.end());
于 2020-11-30T11:45:59.713 回答
0

COPY 函数将一个迭代器返回到目标范围的末尾(它指向复制的最后一个元素之后的元素)。

反向插入迭代器是一种特殊类型的输出迭代器,旨在允许通常覆盖元素(例如复制)的算法在容器末尾自动插入新元素。

设置操作系统;向量向量;

复制(os.begin(),os.end(),back_inserter(vec));

于 2021-04-27T15:50:07.137 回答