这是在op的评论部分提出的,但我想我会在答案部分回应:
Ranges 库看起来很有前途,但我对这个返回的汽车有点担心。
请记住,即使添加auto
,C++是一种强类型语言。就你而言,既然你要回来evens
,那么返回类型将与evens
。 (从技术上讲,它将是evens
, but evens
无论如何都是一个值类型)
In fact, you probably really don't want to type out the return type manually: std::ranges::filter_view<std::ranges::ref_view<const std::vector<int>>, MyClass::getEvens() const::<decltype([](int i) {return ! (i % 2);})>>
(141 characters)
- 正如 @Caleth 在评论中提到的,事实上,这也不起作用
evens
是在函数内部定义的 lambda,即使两个不同的 lambda 基本相同,其类型也会不同,因此实际上无法在此处获取完整的返回类型。
虽然对于是否使用可能存在争议auto
或在不同情况下不使用,但我相信大多数人都会使用auto
这里。再加上你的evens
被宣布为auto
同样,输入类型只会降低这里的可读性。
那么,如果我想访问子集(例如偶数),我有什么选择?无论是否有 Ranges 库,我还应该考虑其他方法吗?
根据您访问返回数据的方式和数据类型,您可能会考虑返回std::vector<T*>
.
views
确实应该从头到尾看一遍。虽然你可以使用views::drop
and views::take
为了限制为单个元素,它还没有提供下标运算符。
计算上也会存在差异。vector
需要预先计算,其中views
是在迭代时计算的。所以当你这样做时:
for(auto i : myObject.getEven())
{
std::cout << i;
}
在幕后,它基本上在做:
for(auto i : myObject.vec)
{
if(!(i % 2)) std::cout << i;
}
取决于数据量和计算的复杂性,views
可能会快很多,或者与vector
方法。此外,您可以轻松地在同一范围内应用多个过滤器,而无需多次迭代数据。
最后,您可以随时存储view
in a vector
:
std::vector<int> vec2(evens.begin(), evens.end());
所以我的建议是,如果你有范围库, 然后你should use it.
If not, then vector<T>
, vector<T*>
, vector<index>
depending on the size and copiability of T.