Каков минимальный способ копирования и вставки для применения конструктора преобразования с использованием std::ranges::C++

Программы на C++. Форум разработчиков
Ответить Пред. темаСлед. тема
Anonymous
 Каков минимальный способ копирования и вставки для применения конструктора преобразования с использованием std::ranges::

Сообщение Anonymous »

Я работаю над синтаксическим анализатором constexpr, который анализирует текстовый файл и генерирует представление объекта.
Я использую G++ 14.1.0, но также было бы неплохо переключиться (сейчас у меня такое ощущение, что G++ поддерживает больше современных C++, чем CLang).
Я использую std::ranges::views:: разбить там много, а затем преобразовать значения в std::string_view через std::ranges::views::split.
Минимальный пример кода:

Код: Выделить всё

#include 
#include 

using namespace std::literals::string_view_literals;

int main() {
constexpr std::string_view input = "A,B B,C C,D C,E D,F"sv;
constexpr auto working =
input | std::ranges::views::split(","sv) |
std::ranges::views::transform(
[](const auto input) { return std::string_view(input); });
}
Поскольку здесь требуется много копирования и вставки, что затрудняет чтение кода, я попытался переместить вызов конструктора преобразования или даже все преобразование в функцию constexpr.< /p>
Первое, что я попробовал:

Код: Выделить всё

#include 
#include 

using namespace std::literals::string_view_literals;

int main() {
constexpr std::string_view input = "A,B B,C C,D C,E D,F"sv;
constexpr auto working =
input | std::ranges::views::split(","sv) |
std::ranges::views::transform(std::string_view::string_view);
}
, что приводит к ошибке: 'string_view' не является членом 'std::string_view' {он же 'std::basic_string_view'
и:

Код: Выделить всё

#include 
#include 

using namespace std::literals::string_view_literals;

int main() {
constexpr std::string_view input = "A,B B,C C,D C,E D,F"sv;
constexpr auto working =
input | std::ranges::views::split(","sv) |
std::ranges::views::transform(std::string_view);
}
, что приводит к ошибке: ожидаемое первичное выражение перед ')'.
Третий вариант, который я попробовал:
p>

Код: Выделить всё

#include 
#include 
#include 

using namespace std::literals::string_view_literals;

[[nodiscard]] static constexpr std::string_view to_string_view(const auto input)
requires(std::constructible_from)
{
return std::string_view(input);
}

int main() {
constexpr std::string_view input = "A,B B,C C,D C,E D,F"sv;
constexpr auto test = std::ranges::views::transform(
input | std::ranges::views::split(","sv), to_string_view);
}
, что приводит к ошибке.

Код: Выделить всё

> : In function 'int main()':
> :15:56: error: no match for call to '(const std::ranges::views::_Transform) (std::ranges::split_view, )'
>    15 |     constexpr auto test = std::ranges::views::transform(
>       |                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
>.   16 |         input | std::ranges::views::split(","sv), to_string_view);
>       |         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> In file included from :2:
> /opt/compiler-explorer/gcc-trunk-20240629/include/c++/15.0.0/ranges:2212:9: note: candidate: 'template  requires (viewable_range) && (__can_transform_view) constexpr auto std::ranges::views::_Transform::operator()(_Range&&, _Fp&&) const'
>  2212 |         operator() [[nodiscard]] (_Range&& __r, _Fp&& __f) const
>       |         ^~~~~~~~
> /opt/compiler-explorer/gcc-trunk-20240629/include/c++/15.0.0/ranges:2212:9: note:   template argument deduction/substitution failed:
> :15:56: note:   couldn't deduce template parameter '_Fp'
>.    15 |     constexpr auto test = std::ranges::views::transform(
>       |                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
>    16 |         input | std::ranges::views::split(","sv), to_string_view);
>       |         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> /opt/compiler-explorer/gcc-trunk-20240629/include/c++/15.0.0/ranges:991:9: note: candidate: 'template  requires  __adaptor_partial_app_viable constexpr auto std::ranges::views::__adaptor::_RangeAdaptor::operator()(_Args&& ...) const [with _Args = {_Args ...}; _Derived = std::ranges::views::_Transform]'
>   991 |         operator()(_Args&&... __args) const
>       |         ^~~~~~~~
> /opt/compiler-explorer/gcc-trunk-20240629/include/c++/15.0.0/ranges:991:9: note:   template argument deduction/substitution failed:
> /opt/compiler-explorer/gcc-trunk-20240629/include/c++/15.0.0/ranges:991:9: note: constraints not satisfied
> /opt/compiler-explorer/gcc-trunk-20240629/include/c++/15.0.0/ranges: In substitution of 'template  requires  __adaptor_partial_app_viable constexpr auto std::ranges::views::__adaptor::_RangeAdaptor::operator()(_Args&& ...) const [with _Args = std::ranges::views::_Transform]':
> :15:56:   required from here
>    15 |     constexpr auto test = std::ranges::views::transform(
>       |                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
>    16 |         input | std::ranges::views::split(","sv), to_string_view);
>       |         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> /opt/compiler-explorer/gcc-trunk-20240629/include/c++/15.0.0/ranges:921:13:   required for the satisfaction of '__adaptor_partial_app_viable' [with _Derived = std::ranges::views::_Transform; _Args = {}]
> /opt/compiler-explorer/gcc-trunk-20240629/include/c++/15.0.0/ranges:922:28: note: the expression 'sizeof ... (_Args ...) == (_Adaptor::_S_arity) - 1 [with _Args = {}; _Adaptor = std::ranges::views::_Transform]' evaluated to 'false'
>   922 |       && (sizeof...(_Args) == _Adaptor::_S_arity - 1)
>       |          ~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~
> Compiler returned: 1
Думаю, проблема в том, что to_string_view не создается для определенных типов, и поэтому компилятор его не находит, но это предположение.
Поэтому я попытался напрямую попытаться достичь конечной цели и перенести все преобразование в функцию:

Код: Выделить всё

#include 
#include 
#include 
#include 

using namespace std::literals::string_view_literals;

static auto constexpr to_string_transform_view = std::bind_back(
std::ranges::views::transform, [](const auto input)
requires(std::constructible_from)
{ return std::string_view(input); });

int main() {
constexpr std::string_view input = "A,B B,C C,D C,E D,F"sv;
auto constexpr test =
to_string_transform_view(input | std::ranges::views::split(","sv));
}
Требуется помощь: Это компилируется, но я теряю красивый синтаксис |, который гораздо удобнее читать. Как я могу улучшить это так, чтобы определение to_string_transform_view не становилось (слишком) хуже читаемым?
Кроме того, у меня, окей, только один раз есть эта «уродливая» лямбда функция там для очень простой вещи.
Поскольку мне это нужно и для других вещей, я бы предпочел лучший способ.
Благодаря различным ответам в StackOverflow я увидел это boost дает два варианта:

Код: Выделить всё

#include 
#include 
#include 
#include 

#include 

using namespace std::literals::string_view_literals;

static auto constexpr to_string_transform_view = std::bind_back(
std::ranges::views::transform, boost::value_factory());

int main() {
constexpr std::string_view input = "A,B B,C C,D C,E D,F"sv;
auto constexpr test =
to_string_transform_view(input | std::ranges::views::split(","sv));
}

Код: Выделить всё

#include 
#include 
#include 
#include 

#include 

using namespace std::literals::string_view_literals;

static auto constexpr to_string_transform_view = std::bind_back(
std::ranges::views::transform, boost::lambda::constructor());

int main() {
constexpr std::string_view input = "A,B B,C C,D C,E D,F"sv;
auto constexpr test =
to_string_transform_view(input | std::ranges::views::split(","sv));
}
Вопросы на этот счет:
  • Существуют ли только две реализации одного и того же объекта?
  • Подходит ли один для некоторых случаев лучше, чем другой?
  • Есть ли способ обойтись без сторонних библиотек?


Подробнее здесь: https://stackoverflow.com/questions/786 ... -using-std
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение
  • Почему std :: ranges :: find_if возвращает итератор, но std :: ranges :: find_last_if возвращает подпакну?
    Anonymous » » в форуме C++
    0 Ответы
    9 Просмотры
    Последнее сообщение Anonymous
  • Каково использование std :: ranges :: views :: lazy_split, когда у нас есть std :: ranges :: views :: split?
    Anonymous » » в форуме C++
    0 Ответы
    16 Просмотры
    Последнее сообщение Anonymous
  • Каков статус std::ranges::split_view в C++20?
    Гость » » в форуме C++
    0 Ответы
    20 Просмотры
    Последнее сообщение Гость
  • Каков самый быстрый способ преобразования std::shared_ptr>?
    Anonymous » » в форуме C++
    0 Ответы
    8 Просмотры
    Последнее сообщение Anonymous
  • Каков самый быстрый способ преобразования std::shared_ptr>?
    Anonymous » » в форуме C++
    0 Ответы
    5 Просмотры
    Последнее сообщение Anonymous

Вернуться в «C++»