代码之家  ›  专栏  ›  技术社区  ›  CygnusX1 Stack Overflow is garbage

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

  •  0
  • CygnusX1 Stack Overflow is garbage  · 技术社区  · 7 年前

    我想将一个范围存储为类中的一个字段,以便以后可以多次重用它。但是,与局部变量不同,我不能简单地将其类型指定为 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并获得 解密 工作?
    • 或者有更好/更干净的方法来获取一个范围类型,以便将其声明为类中的字段?
    1 回复  |  直到 7 年前
        1
  •  3
  •   CygnusX1 Stack Overflow is garbage    7 年前

    这里的语言很有用:如果lambda在 decltype ,这对您没有帮助,因为您无法生成类型的值 MyRange 除了通过默认初始化。由于lambda表达式的出现具有唯一的类型,因此无法生成要传递到的正确类型的函数对象 view::filter 让它返回你可以存储在 己方范围 .

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

    推荐文章