如何从C风格的数组初始化std :: vector?

时间:2010-03-12 16:37:09

标签: c++ arrays vector stl

从C风格的数组初始化std::vector的最便宜的方法是什么?

示例:在下面的类中,我有vector,但由于外部限制,数据将作为C样式数组传递:

class Foo {
  std::vector<double> w_;
public:
  void set_data(double* w, int len){
   // how to cheaply initialize the std::vector?
}

显然,我可以调用w_.resize()然后循环遍历元素,或者调用std::copy()。还有更好的方法吗?

6 个答案:

答案 0 :(得分:204)

不要忘记您可以将指针视为迭代器:

w_.assign(w, w + len);

答案 1 :(得分:37)

你使用“初始化”这个词,所以不清楚这是一次性作业还是多次发生。

如果您只需要一次初始化,可以将它放在构造函数中并使用两个迭代器向量构造函数:

Foo::Foo(double* w, int len) : w_(w, w + len) { }

否则使用如前所述的分配:

void set_data(double* w, int len)
{
    w_.assign(w, w + len);
}

答案 2 :(得分:11)

嗯,Pavel很接近,但是从c风格的数组中初始化顺序容器甚至还有一个更简单优雅的解决方案。

在你的情况下:

w_ (array, std::end(array))
  • 数组会给我们一个指向数组开头的指针(没有抓住它的名字),
  • std :: end(array)将为我们提供一个到数组末尾的迭代器。

答案 3 :(得分:9)

你可以学习&#39;数组的大小自动:

template<typename T, size_t N>
void set_data(const T (&w)[N]){
    w_.assign(w, w+N);
}

希望您可以将界面更改为set_data,如上所示。它仍然接受C风格的数组作为它的第一个参数。它恰好通过引用来接受它。


工作原理

[更新:请参阅here了解有关学习规模的更全面的讨论]

这是一个更通用的解决方案:

template<typename T, size_t N>
void copy_from_array(vector<T> &target_vector, const T (&source_array)[N]) {
    target_vector.assign(source_array, source_array+N);
}

这是有效的,因为数组作为引用到数组传递。在C / C ++中,您不能将数组作为函数传递,而是会衰减到指针并且您会丢失大小。但是在C ++中,可以传递对数组的引用。

通过引用传递数组要求类型完全匹配。数组的大小是其类型的一部分。这意味着我们可以使用模板参数N来了解我们的大小。

使用返回向量的函数可能更简单。通过适当的编译器优化,这应该比它看起来更快。

template<typename T, size_t N>
vector<T> convert_array_to_vector(const T (&source_array)[N]) {
    return vector<T>(source_array, source_array+N);
}

答案 4 :(得分:1)

快速的通用答案:

std::vector<double> vec(carray,carray+carray_size); 

或特定问题:

std::vector<double> w_(w,w+len); 

基于above别忘了您可以将指针视为迭代器

答案 5 :(得分:0)

std::vector<double>::assign是要走的路,因为它是小代码。但实际上它是如何工作的呢?它不会调整大小然后复制吗?在STL的MS实现中,我正在使用它。

我担心没有更快的方式来实施(重新)初始化std::vector