是否可以将向量的一部分作为向量发送到函数? [重复]

问题描述 投票:4回答:3

这个问题在这里已有答案:

我想看看是否可以将部分向量传递给函数,使其显示为函数的法线向量。更重要的是,我希望在O(1),恒定时间内完成。我不想迭代向量来创建一个新的向量。实际上,我还希望在以下示例中将新矢量的大小更改为40。

void func(vector <int> &v){

    //calling index 10  to 50 of v
    func(v[10..50])
}
c++ vector pass-by-reference
3个回答
5
投票

使用迭代器作为基于范围的函数的参数,并传递所需的范围。你的函数代码变成了

funcWithRange(v.cbegin()+10, v.cbegin()+50);

带功能签名

void funcWithRange(std::vector<int>::const_iterator first, std::vector<int>::const_iterator last)

这可以通过使用vector成员类型作为其模板参数的函数模板来推广,或者更进一步支持任何支持此类范围迭代的容器。正如评论中所指出的那样,<algorithm>有很多这种模式的例子。

std::distance(first, last);将返回所需的改变大小。我不认为你可以在不制作实物副本的情况下更接近满足你的要求。


2
投票

有一种方法可以实现类似于此的建议,以包含在C++标准中。它被称为span,它在某些方面像矢量一样运作。

#include <gsl/span>

void func(gsl::span<int> sp)
{
    for(auto& i: sp)
        std::cout << i << '\n';
}

int main()
{
    // ...

    std::vector<int> v(100);

    // put something in the vector (numbers 0 - 99)
    std::iota(std::begin(v), std::end(v), 0);

    // wrap the container in a span
    auto sp = gsl::make_span(v);

    // send parts of it to functions
    func(sp.subspan(10, 50));
}

span在原始矢量上显示一个窗口,因此它是一个参考类型。它不包含自己的数据,只是指向向量中的数据。因此,它们重量轻,旨在通过价值传递。

span的实现可以在这里找到:https://github.com/Microsoft/GSL

这是Bjarne Stroustrup和Herb Sutter在Best Practices指南中传递连续容器的推荐方法。

指南可以在这里找到:CppCoreGuidelines.md


1
投票

如果你有一个说100个元素的向量

std::vector<int> v(100);

并且你想用前10个元素调用void f(std::vector<int> v),只需将函数调用为

f({v.cbegin(), v.cbegin() + 10});

这将从两个迭代器构造一个新的向量(通过复制元素)并将新向量传递给f

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