如何将范围存储为 class 中的字段?

How to store a range as a field in a class?

我想将一个范围存储为 class 中的一个字段,以便以后可以多次重复使用它。但是,与局部变量不同,我不能简单地将其类型指定为 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

那么,我的问题是:

语言在这里很有用:如果在 decltype 中允许使用 lambda,它对您没有帮助,因为您无法生成 MyRange 类型的值除了通过默认初始化。由于 lambda 表达式的每次出现都具有唯一类型,因此您无法生成正确类型的函数对象以传递给 view::filter 以将其传递给 return 可以存储在 [=12 中的内容=].

解决方法是"don't do that";例如,将您的函数对象存储在某处并在 decltype 中引用它。在 C++17 中,for example:

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& 的用法。这是必需的,如

中所述