从c风格数组初始化std::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()。有没有更好的方法?


当前回答

别忘了你可以把指针当作迭代器:

w_.assign(w, w + len);

其他回答

简单的回答是:

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

或者具体问题:

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

不要忘记你可以把指针当作迭代器

好吧,Pavel已经很接近了,但是还有一个更简单和优雅的解决方案,可以从c风格的数组初始化一个顺序容器。

在你的情况下:

w_ (array, std::end(array))

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

你可以自动“学习”数组的大小:

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

希望您可以像上面那样将接口更改为set_data。它仍然接受c风格数组作为第一个参数。它只是碰巧引用了它。


它是如何工作的

[更新:在这里查看关于学习大小的更全面的讨论]

下面是一个更普遍的解决方案:

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

Std::vector<double>::assign是正确的方法,因为它的代码很小。但它到底是如何工作的呢?它不是调整大小然后复制吗?在MS实现的STL我正在使用它完全这样做。

恐怕没有更快的方法来实现(重新)初始化你的std::vector。

你使用了初始化这个词,所以不清楚这是一次赋值还是可以发生多次。

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

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

否则,按照之前的建议使用assign:

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