首页 > 解决方案 > 如何将范围存储为类中的字段?

问题描述

我想将一个范围存储为一个类中的一个字段,以便以后可以多次重复使用它。但是,与局部变量不同,我不能简单地将其类型指定为auto. 另一方面,库创建的范围类型非常复杂。手动找出正确的类型将花费我不成比例的长时间+如果我选择更改获取范围的方式,将来将无法维护。

所以,我想,也许我可以decltype用来帮助自己:

class MyClass {
    public:
    using MyRange = decltype(std::declval<std::vector<int*>>() | ranges::v3::view::filter([=](int* elem) { return true; }));
    MyRange range;
}

(注意:我的实际std::declval情况实际上更复杂,但我想让这个例子简短一些。)

但我收到一个错误: a lambda cannot appear in an unevaluated context

所以,我的问题是:

标签: c++range-v3

解决方案


该语言在这里很有帮助:如果允许 lambda decltype,它不会帮助你,因为MyRange除了通过默认初始化之外,你无法生成类型的值。由于 lambda 表达式的出现具有唯一类型,因此您无法生成要传递给的正确类型的函数对象以view::filter使其返回可以存储在MyRange.

解决方法是“不要那样做”;例如,将您的函数对象存储在某处并在decltype. 在 C++17 中,例如

struct MyClass {
    static constexpr auto pred = [](int* elem) { return true; };
    using MyRange = decltype(std::declval<std::vector<int*>&>() | ranges::v3::view::filter(pred));
    MyRange range;
};

注意使用std::vector&. 这是必需的,如Explicit range-v3 decltype evaluates to void?


推荐阅读