如何使用 C 风格数组分配 std::vector?

问题描述 投票:0回答:6

从 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()
。有没有更好的方法?

c++ arrays vector stl stdvector
6个回答
306
投票

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

w_.assign(w, w + len);

49
投票

您使用了“初始化”一词,因此不清楚这是一次性分配还是可以多次发生。

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

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

否则请按照之前的建议使用分配:

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

18
投票

快速通用答案:

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

或具体问题:

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

基于上面不要忘记你可以将指针视为迭代器


17
投票

嗯,Pavel 已经很接近了,但是还有一个更简单、更优雅的解决方案来从 C 样式数组初始化顺序容器。

您的情况:

w_ (array, std::end(array))
  • array 将为我们提供一个指向数组开头的指针(没有捕获它的名称),
  • std::end(array) 将为我们提供一个指向数组末尾的迭代器。

12
投票

您可以自动“了解”数组的大小:

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

0
投票

std::vector<double>::assign
是正确的方法,因为它是小代码。但实际上它是如何运作的呢?不是先调整大小然后复制吗?在我使用的 STL 的 MS 实现中,它正是这样做的。

恐怕没有更快的方法来实现(重新)初始化您的

std::vector

© www.soinside.com 2019 - 2024. All rights reserved.