【问题标题】:How to store a range as a field in a class?如何将范围存储为类中的字段?
【发布时间】:2018-11-29 19:56:03
【问题描述】:

我想将一个范围作为一个字段存储在一个类中,以便以后可以多次重复使用它。但是,与局部变量不同,我不能简单地将其类型指定为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 正常工作?
  • 或者也许有更好/更简洁的方法来获取范围类型,以便将其声明为类中的字段?

【问题讨论】:

    标签: c++ range-v3


    【解决方案1】:

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

    解决方法是“不要那样做”;例如,将您的函数对象存储在某处并在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&amp; 的使用。如Explicit range-v3 decltype evaluates to void?中所述,这是必需的

    【讨论】:

      猜你喜欢
      • 2023-03-19
      • 2020-08-24
      • 1970-01-01
      • 2015-04-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-29
      • 2019-05-18
      相关资源
      最近更新 更多