Как сохранить диапазон как поле в классе? - PullRequest
0 голосов
/ 29 ноября 2018

Я хотел бы сохранить диапазон в виде поля в классе, чтобы впоследствии я мог использовать его несколько раз.Однако, в отличие от локальных переменных, я не могу просто указать его тип как 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 Ответ

0 голосов
/ 29 ноября 2018

Здесь очень полезен язык: если бы лямбда была разрешена в decltype, это не помогло бы вам, потому что у вас не было бы возможности получить значение типа MyRange, отличное от инициализации по умолчанию,Так как само вхождение лямбда-выражения имеет уникальный тип, вы не можете создать функциональный объект правильного типа для передачи в view::filter, чтобы он возвращал что-то, что вы можете сохранить в MyRange.

* 1006.* Обходной путь - «не делай этого»;например, где-нибудь хранить свой функциональный объект и ссылаться на него в 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&.Это требуется, как объяснено в Явный range-v3 decltype оценивает как void?

...