如何从 C 样式数组初始化 std::vector?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2434196/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 23:27:59  来源:igfitidea点击:

How to initialize std::vector from C-style array?

c++arraysvectorstl

提问by Frank

What is the cheapest way to initialize a std::vectorfrom a C-style array?

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

Example: In the following class, I have a vector, but due to outside restrictions, the data will be passed in as C-style array:

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

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

Obviously, I can call w_.resize()and then loop over the elements, or call std::copy(). Are there any better methods?

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

回答by Pavel Minaev

Don't forget that you can treat pointers as iterators:

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

w_.assign(w, w + len);

回答by Mark B

You use the word initialize so it's unclear if this is one-time assignment or can happen multiple times.

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

If you just need a one time initialization, you can put it in the constructor and use the two iterator vector constructor:

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

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

Otherwise use assign as previously suggested:

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

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

回答by Aaron McDaid

You can 'learn' the size of the array automatically:

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

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

Hopefully, you can change the interface to set_data as above. It still accepts a C-style array as its first argument. It just happens to take it by reference.

希望您可以将接口更改为 set_data 如上所述。它仍然接受一个 C 风格的数组作为它的第一个参数。它只是碰巧通过引用来获取它。



How it works

这个怎么运作

[ Update: See herefor a more comprehensive discussion on learning the size ]

[更新:有关学习大小的更全面讨论,请参见此处]

Here is a more general solution:

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

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

This works because the array is being passed as a reference-to-an-array. In C/C++, you cannot pass an array as a function, instead it will decay to a pointer and you lose the size. But in C++, you canpass a reference to the array.

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

Passing an array by reference requires the types to match up exactly. The size of an array is part of its type. This means we can use the template parameter N to learn the size for us.

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

It might be even simpler to have this function which returns a vector. With appropriate compiler optimizations in effect, this should be faster than it looks.

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

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

回答by Mugurel

Well, Pavel was close, but there's even a more simple and elegant solution to initialize a sequential container from a c style array.

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

In your case:

在你的情况下:

w_ (array, std::end(array))
  • array will get us a pointer to the beginning of the array (didn't catch it's name),
  • std::end(array) will get us an iterator to the end of the array.
  • array 会给我们一个指向数组开头的指针(没有抓住它的名字),
  • std::end(array) 会给我们一个迭代器到数组的末尾。

回答by eusoubrasileiro

The quick generic answer:

快速通用答案:

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


or question specific:

或具体问题:

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


based on above: Don't forget that you can treat pointers as iterators

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

回答by Janusz Lenar

std::vector<double>::assignis the way to go, because it's little code. But how does it work, actually? Doesnt't it resize and then copy? In MS implementation of STL I am using it does exactly so.

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

I'm afraid there's no faster wayto implement (re)initializing your std::vector.

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