我们可以将部分向量作为函数参数发送吗?

时间:2013-06-07 11:45:26

标签: c++ vector

我在c ++程序中使用vector(我是初学者) 我需要将vector的一部分发送给一个函数。

如果是c我需要这样做(使用数组):

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

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

7 个答案:

答案 0 :(得分:24)

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

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+中使用的v.begin()+2增量。有关替代方案,请查看std::advancestd::next

答案 1 :(得分:6)

通常你可以发送迭代器。

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

这不仅仅适用于vector。但是,由于vector保证了可靠的存储空间,因此只要vector不重新分配,您就可以发送元素的地址:

func (&vec[1], &vec[3]);

答案 2 :(得分:4)

最新的 (C++20) 方法是使用 std::span 创建一个 std::span查看 {{1 }} 并将其传递给函数。注意:元素在内存中必须是连续的才能在容器上使用 std::vectorstd::vector is continuous in memory

std::span

答案 3 :(得分:1)

std::vector<char> b(100); 
send(z,&b[0],b.size(),0);

试试这个。

Read this too.

答案 4 :(得分:0)

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

如果您需要更多灵活性,请查看slice。使用slice,您可以检索向量的每个第n个条目。

答案 5 :(得分:0)

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

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

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

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

答案 6 :(得分:0)

C++20 开始,我将使用 Ranges library 中的 range,因为它提供了各种范围适配器,用于在您的矢量上创建不同的视图。对于您的用例,我将使用范围适配器 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;
}

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

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

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

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

输出:

<块引用>

3
4
5

Code on Wandbox