Lia*_*cre 10 c++ range-v3 c++20
我正在使用范围库来帮助我的类中的文件管理器数据,如下所示:
class MyClass
{
public:
MyClass(std::vector<int> v) : vec(v) {}
std::vector<int> getEvens() const
{
auto evens = vec | ranges::views::filter([](int i) { return ! (i % 2); });
return std::vector<int>(evens.begin(), evens.end());
}
private:
std::vector<int> vec;
};
Run Code Online (Sandbox Code Playgroud)
在这种情况下,函数中构造了一个新向量getEvents()。为了节省这种开销,我想知道是否可以/建议直接从函数返回范围?
class MyClass
{
public:
using RangeReturnType = ???;
MyClass(std::vector<int> v) : vec(v) {}
RangeReturnType getEvens() const
{
auto evens = vec | ranges::views::filter([](int i) { return ! (i % 2); });
// ...
return evens;
}
private:
std::vector<int> vec;
};
Run Code Online (Sandbox Code Playgroud)
如果可能的话,我是否需要考虑任何终生注意事项?
我也有兴趣知道是否可以/建议将范围作为参数传递,或将其存储为成员变量。或者范围库更适合在单个函数的范围内使用?
小智 5
在 c++23 中,您可以使用std::generator和co_yield std::ranges::elements_of
class MyClass
{
public:
MyClass(std::vector<int> v) : vec(v) {}
std::generator<int> getEvens() const
{
auto evens = vec | std::ranges::views::filter([](int i) { return ! (i % 2); });
co_yield std::ranges::elements_of(evens);
}
private:
std::vector<int> vec;
};
int main() {
MyClass mc{{1,2,3,4,5,6,7,8,9}};
for (int i : mc.getEvens()) {
std::cout << i << '\n';
}
}
Run Code Online (Sandbox Code Playgroud)
工作演示(GCC 13.1 不带std::ranges::elements_of):https ://godbolt.org/z/oehd59oEz
标准中对STL组件的使用没有限制。当然,有一些最佳实践(例如,string_view代替string const &)。
在这种情况下,我可以预见直接处理视图返回类型不会出现问题。也就是说,最佳实践尚未确定,因为该标准太新,而且还没有编译器具有完整的实现。
在我看来,你可以选择以下内容:
class MyClass
{
public:
MyClass(std::vector<int> v) : vec(std::move(v)) {}
auto getEvens() const
{
return vec | ranges::views::filter([](int i) { return ! (i % 2); });
}
private:
std::vector<int> vec;
};
Run Code Online (Sandbox Code Playgroud)