是否可以将向量的一部分作为向量发送给函数?
Is it possible to send part of vector as a vector to a function?
我想看看是否可以将矢量的一部分传递给一个函数,使其显示为函数的法线矢量。更重要的是,我希望这在 O(1) 常数时间内完成。我不想迭代向量来制作一个新向量。其实我也想在下面的例子中把新vector的size改成40
void func(vector <int> &v){
//calling index 10 to 50 of v
func(v[10..50])
}
使用迭代器作为基于范围的函数的参数,并传入所需的范围。您在函数中的代码变为
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);
将 return 更改为所需的大小。我认为如果不制作实体副本,您就无法更接近于满足您的要求。
如果你有一个包含 100 个元素的向量
std::vector<int> v(100);
并且您想用前 10 个元素调用 void f(std::vector<int> v)
,只需将函数调用为
f({v.cbegin(), v.cbegin() + 10});
这将从两个迭代器构造一个新向量(通过复制元素)并将新向量传递给 f
。
有一种方法可以实现与此类似的东西,并提议将其包含在 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
将 window 呈现在原始向量上,因此它是 引用类型 。它不包含自己的数据,只是指向向量中数据的指针。因此,它们是轻量级的,旨在按值传递。
可在此处找到 span
的实现:https://github.com/Microsoft/GSL
这是 Bjarne Stroustrup 和 Herb Sutter 的 最佳实践 指南中推荐的传递连续容器的方法。
指南可在此处找到:CppCoreGuidelines.md
我想看看是否可以将矢量的一部分传递给一个函数,使其显示为函数的法线矢量。更重要的是,我希望这在 O(1) 常数时间内完成。我不想迭代向量来制作一个新向量。其实我也想在下面的例子中把新vector的size改成40
void func(vector <int> &v){
//calling index 10 to 50 of v
func(v[10..50])
}
使用迭代器作为基于范围的函数的参数,并传入所需的范围。您在函数中的代码变为
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);
将 return 更改为所需的大小。我认为如果不制作实体副本,您就无法更接近于满足您的要求。
如果你有一个包含 100 个元素的向量
std::vector<int> v(100);
并且您想用前 10 个元素调用 void f(std::vector<int> v)
,只需将函数调用为
f({v.cbegin(), v.cbegin() + 10});
这将从两个迭代器构造一个新向量(通过复制元素)并将新向量传递给 f
。
有一种方法可以实现与此类似的东西,并提议将其包含在 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
将 window 呈现在原始向量上,因此它是 引用类型 。它不包含自己的数据,只是指向向量中数据的指针。因此,它们是轻量级的,旨在按值传递。
可在此处找到 span
的实现:https://github.com/Microsoft/GSL
这是 Bjarne Stroustrup 和 Herb Sutter 的 最佳实践 指南中推荐的传递连续容器的方法。
指南可在此处找到:CppCoreGuidelines.md