0

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

所以,我的问题是:

  • 如何避免使用 lambda 并开始decltype工作?
  • 或者也许有更好/更清洁的方法来获取范围类型以便将其声明为类中的字段?
4

1 回答 1

3

该语言在这里很有帮助:如果允许 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?

于 2018-11-29T20:17:12.060 回答