Как сохранить диапазон как поле в классе?
Я хотел бы сохранить диапазон в виде поля в классе, чтобы впоследствии я мог использовать его несколько раз. Однако, в отличие от локальных переменных, я не могу просто указать его тип как 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
за работой? - Или, может быть, есть лучший / более чистый способ получить тип диапазона, чтобы объявить его как поле в классе?
1 ответ
Здесь полезен язык: если бы лямбда была допущена в decltype
, это не помогло бы вам, потому что у вас не было бы способа вывести значение типа MyRange
кроме как через default-initialization. Поскольку само появление лямбда-выражения имеет уникальный тип, вы не можете создать объект функции правильного типа для передачи 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;
};