我想看看是否可以将部分向量传递给函数,使其显示为函数的法线向量。更重要的是,我希望在O(1),恒定时间内完成。我不想迭代向量来创建一个新的向量。实际上,我还希望在以下示例中将新矢量的大小更改为40。
void func(vector <int> &v){
//calling index 10 to 50 of v
func(v[10..50])
}
答案 0 :(得分: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);
将返回所需的更改大小。我不认为你可以在不制作实物副本的情况下更接近满足你的要求。
答案 1 :(得分: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在最佳实践指南中传递连续容器的推荐方法。
可以在此处找到指南:CppCoreGuidelines.md
答案 2 :(得分:1)
如果你有一个说100个元素的向量
std::vector<int> v(100);
并且您希望使用前10个元素调用void f(std::vector<int> v)
,只需将函数调用为
f({v.cbegin(), v.cbegin() + 10});
这将从两个迭代器构造一个新的向量(通过复制元素)并将新向量传递给f
。