Гарантируется ли корректная работа std::views::keys с любым типом пары/кортежа? ⇐ C++
Гарантируется ли корректная работа std::views::keys с любым типом пары/кортежа?
Код вставлен сюда и https://www.godbolt.org/z/qszqYsT4o
Я пытаюсь предоставить функциональность boost::adaptors::indexed, совместимую с представлениями C++20. Мой основной вариант использования — std::vector, но я бы определенно предпочел универсальное решение. Я был шокирован, обнаружив, что std::views::keys не работает должным образом и правильно извлекает первый элемент.
Для GCC 10.3 вывод rng1 является мусором, а rng2 соответствует ожиданиям. GCC 10.4+ работает нормально. Последняя версия clang не может скомпилировать код.
Вопросы:
[*]Гарантированно ли std::views::keys поддерживает любой тип пары/кортежа или мой код UB? [*]Учитывая, что clang 14.0.0 не компилируется, является ли мой код допустимым для C++? [*]Есть ли лучший способ реализовать эту функциональность в C++20? Я немного присматривался к std::span, но, похоже, не смог заставить его работать естественным образом. Примечание. Я бы с удовольствием использовал std::views::zip с std::views::iota, если бы он был доступен. #include #include #include шаблон используя IndexValuePair = std::pair; шаблон auto make_indexed_view(std::vector& vec) { авто fn = [&vec](T& val) { return IndexValuePair{static_cast(&val - vec.data()), val}; }; return std::views::all(vec) | std::views::transform(fn); } шаблон auto make_indexed_view(const std::vector& vec) { auto fn = [&vec](const T& val) { return IndexValuePair{static_cast(&val - vec.data()), val}; }; return std::views::all(vec) | std::views::transform(fn); } структура GetFirstSafely { шаблон const T1& оператор()(const std::pair& p) const { return std::get(p); } шаблон T1operator()(std::pair&& p) const { return std::get(std::move(p)); } }; auto get_first = [](auto&& p) -> decltype(auto) { return GetFirstSafely{}(std::forward(p)); }; интервал основной() { const std::vector v{10, 20, 30}; auto fn = [](const auto& val) { return val.секунда >= 20; }; auto rng1 = make_indexed_view(v) | std::views::filter(fn) | станд::views::keys; auto rng2 = make_indexed_view(v) | std::views::filter(fn) | std::views::transform(get_first); для (auto&& элемент: rng1) std::cout
Код вставлен сюда и https://www.godbolt.org/z/qszqYsT4o
Я пытаюсь предоставить функциональность boost::adaptors::indexed, совместимую с представлениями C++20. Мой основной вариант использования — std::vector, но я бы определенно предпочел универсальное решение. Я был шокирован, обнаружив, что std::views::keys не работает должным образом и правильно извлекает первый элемент.
Для GCC 10.3 вывод rng1 является мусором, а rng2 соответствует ожиданиям. GCC 10.4+ работает нормально. Последняя версия clang не может скомпилировать код.
Вопросы:
[*]Гарантированно ли std::views::keys поддерживает любой тип пары/кортежа или мой код UB? [*]Учитывая, что clang 14.0.0 не компилируется, является ли мой код допустимым для C++? [*]Есть ли лучший способ реализовать эту функциональность в C++20? Я немного присматривался к std::span, но, похоже, не смог заставить его работать естественным образом. Примечание. Я бы с удовольствием использовал std::views::zip с std::views::iota, если бы он был доступен. #include #include #include шаблон используя IndexValuePair = std::pair; шаблон auto make_indexed_view(std::vector& vec) { авто fn = [&vec](T& val) { return IndexValuePair{static_cast(&val - vec.data()), val}; }; return std::views::all(vec) | std::views::transform(fn); } шаблон auto make_indexed_view(const std::vector& vec) { auto fn = [&vec](const T& val) { return IndexValuePair{static_cast(&val - vec.data()), val}; }; return std::views::all(vec) | std::views::transform(fn); } структура GetFirstSafely { шаблон const T1& оператор()(const std::pair& p) const { return std::get(p); } шаблон T1operator()(std::pair&& p) const { return std::get(std::move(p)); } }; auto get_first = [](auto&& p) -> decltype(auto) { return GetFirstSafely{}(std::forward(p)); }; интервал основной() { const std::vector v{10, 20, 30}; auto fn = [](const auto& val) { return val.секунда >= 20; }; auto rng1 = make_indexed_view(v) | std::views::filter(fn) | станд::views::keys; auto rng2 = make_indexed_view(v) | std::views::filter(fn) | std::views::transform(get_first); для (auto&& элемент: rng1) std::cout
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение