如何将范围存储为 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
那么,我的问题是:
- 如何避免使用 lambda 并使我的
decltype
正常工作?
- 或者可能有一种 better/cleaner 方法来获取范围类型,以便将其声明为 class 中的一个字段?
语言在这里很有用:如果在 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&
的用法。这是必需的,如
中所述
我想将一个范围存储为 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
那么,我的问题是:
- 如何避免使用 lambda 并使我的
decltype
正常工作? - 或者可能有一种 better/cleaner 方法来获取范围类型,以便将其声明为 class 中的一个字段?
语言在这里很有用:如果在 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&
的用法。这是必需的,如