25

vector在 C++ 程序中使用 a ,我需要将其中的一部分传递vector给函数。

如果是 C,我需要执行以下操作(使用数组):

int arr[5] = {1, 2, 3, 4, 5};
func(arr+2);  // Pass the part of the array {3, 4, 5}

vector除了用最后一部分创建一个新的之外,还有其他方法吗?

4

7 回答 7

32

一种常见的方法是传递迭代器范围。这将适用于所有类型的范围,包括那些属于标准库容器和普通数组的范围:

template <typename Iterator>
void func(Iterator start, Iterator end) 
{
  for (Iterator it = start; it !=end; ++it)
  {
     // do something
  } 
}

然后

std::vector<int> v = ...;
func(v.begin()+2, v.end());

int arr[5] = {1, 2, 3, 4, 5};
func(arr+2, arr+5);

注意:尽管该函数适用于各种范围,但并非所有迭代器类型都支持operator+in 中使用的增量v.begin()+2。对于替代方案,请查看std::advanceand std::next

于 2013-06-07T11:48:17.450 回答
6

Generically you could send iterators.

static const int n[] = {1,2,3,4,5};
vector <int> vec;
copy (n, n + (sizeof (n) / sizeof (n[0])), back_inserter (vec));

vector <int>::iterator itStart = vec.begin();
++itStart; // points to `2`
vector <int>::iterator itEnd = itStart;
advance (itEnd,2); // points to 4

func (itStart, itEnd);

This will work with more than just vectors. However, since a vector has guaranteed contigious storage, so long as the vector doesn't reallocate you can send the addresses of elements:

func (&vec[1], &vec[3]);
于 2013-06-07T11:51:19.590 回答
4

最新的 (C++20) 方法是使用std::span. 创建一个std::span查看其中一部分std::vector并将其传递给函数的视图。注意:元素在内存中必须是连续的才能std::span在容器上使用,并且std::vector在内存中是连续的

#include <span>

std::vector<int> int_vector = {1, 2, 3, 4, 5};
std::span<int> a_span(int_vector.data() + 2, int_vector.size() - 2);
for(const int a : a_span);
for(const int& a : a_span);
function(a_span);
于 2020-12-31T22:49:03.777 回答
1
std::vector<char> b(100); 
send(z,&b[0],b.size(),0);

试试这个。

也读这个。

于 2013-06-07T11:47:43.747 回答
1

C++20开始,我将使用Ranges 库中的范围,因为它提供了各种范围适配器,用于在矢量上创建不同的视图。对于您的用例,我将使用范围适配器,如下所示:std::views::drop

int main() {
    std::vector<int> arr {1, 2, 3, 4, 5};

    // Ignore the first two elements and pass only {3, 4, 5} to func().
    func(arr | std::views::drop(2));

    return 0;
}

这样,您就不必为迭代器或指针/迭代器算术而烦恼。此外,不会为您的 shorted 创建临时向量arr,因为视图适配器drop()会创建一个不包含元素的范围。结果范围只是原始向量的视图arr,但具有自定义的迭代行为。

对于函数参数的声明,func()我将使用占位符类型auto,因为结果范围的类型非常复杂。不过,这会func()生成一个函数模板

void func(auto range) {
    for (int i : range)
        std::cout << i << std::endl;
}

(或者,您可以通过arr引用传递func()并在内部应用范围适配器func()。)

输出:

3
4
5

魔杖盒上的代码

于 2021-03-16T15:37:44.683 回答
0

正如其他一些人已经说过的那样,您可以为此使用迭代器。您必须将序列的开头和序列的结尾传递给您的工作函数。

如果你需要更多的灵活性,你应该看看slice. 例如,slice您可以检索向量的每个第 n 个条目。

于 2013-06-07T12:00:25.800 回答
0

我也遇到了同样的问题。我发现了一个非常好的技巧。假设你想找到范围内的最小值LR包括),arr那么你可以做这样的事情:

vector<int>arr = {4,5,1,3,7};

int minVal = *min_element(begin(arr)+L,begin(arr)+(R+1));

意味着您传递完整的数组和范围,然后您可以应用上述技巧。

于 2015-10-20T10:17:42.143 回答