Существует ли «рекурсивный» формат std::format?

У меня есть такой код:

const std::string first = "|>first {} thing<|";
const std::string second = "|>second thing<|";
const std::string third = "|>third thing<|";
const std::string fourth = "|>fourth thing<|";
const std::string out = std::format("Testing {} format {} string {}", first, second, third, fourth);
std::cout << out << std::endl;

Этот код выводит следующее:

Testing |>first {} thing<| format |>second thing<| string |>third thing<|

Я хотел бы, чтобы код выводил:

Testing |>first |>second thing<| thing<| format |>third thing<| string |>fourth thing<|

Разница в том, что |>first {} thing<| заменен на |>first |>second thing<| thing<|. То есть формат применяется рекурсивно. std::format имеет множество проверок во время компиляции, но теоретически ничто не мешает std::vformat применять рекурсивно.

Прежде чем реализовать эту функциональность самостоятельно, я хотел бы знать, существует ли она в стандартной библиотеке или уже доступно другое надежное решение.

Пример из реального мира:

У меня есть пять (на самом деле около 40) разных запросов, каждый из которых требует data1, data2, data3, ... просто в другом месте. Данные будут известны во время выполнения, но позиция будет известна во время компиляции. У меня есть возможность выбрать пять разных классов запросов или один шаблон с разными специализациями: using Query1 = BasicQuery("BLAH {} BLAH");using Query2 = BasicQuery("BLAH BLAH {}"); и так далее. Это может быть разница как в 1500 строках кода, так и в ~250, а также в более приятном интерфейсе вызова по сравнению с запутанным (одна функция выполнения для каждого класса или функция для каждого запроса, если я решил иметь только один класс со всеми запросами).

Кроме того, добавление функции для каждого запроса — не вариант. Каждый запрос имеет разный тип возвращаемого значения (и даже разное количество возвратов) в зависимости от характера запроса. Класс также обрабатывает анализ возвращаемых данных на основе типа возвращаемого значения и количества возвратов. Специализации шаблонов — действительно хорошее решение этой проблемы. Я надеюсь, что смогу также использовать специализации для самой строки запроса.

Какой кошмар функциональности. Зачем это кому-то нужно?

n. m. could be an AI 28.05.2024 08:34

@n.m.couldbeanAI Например, если у вас есть пять разных запросов, каждый из которых нужно data1, data2, data3, ... просто в другом месте. Данные будут известны во время выполнения, а позиция во время компиляции, тогда у вас будет возможность выбрать пять разных запросов (класс или функция) или один шаблон с разными специализациями: using Query1 = BasicQuery("BLAH {} BLAH"); using Query2 = BasicQuery("BLAH BLAH {}"); и так далее. Это может быть разница как в 1500 строках кода, так и в ~250, а также в более приятном интерфейсе вызова по сравнению со сложным (одна функция execute на класс или функция на запрос).

Eshy 28.05.2024 09:05

Я не понимаю этого предложения: «...но теоретически ничто не мешает std::vformat сделать это». сделать что? применять проверки времени компиляции?

463035818_is_not_an_ai 28.05.2024 09:08

Не могли бы вы отредактировать свой вопрос, указав в комментариях реальный пример? (Хотя я не вижу, насколько здесь полезно поведение вложенности.) В противном случае мы могли бы предложить что-то недостаточно общее.

Botje 28.05.2024 09:09

@463035818_is_not_an_ai std::format проверяет строку формата во время компиляции. Возможно, одна из рекурсивных строк неизвестна до времени выполнения. Поэтому std::format не может это проверить. std::vformat существует как полностью динамический вариант std::format. Под «сделать это» я имею в виду рекурсивное функционирование, поскольку знание времени компиляции не имеет значения для std::vformat.

Eshy 28.05.2024 09:10

@Botje, я обновил это

Eshy 28.05.2024 09:16

честно говоря, описание вашего варианта использования расплывчато. Не сосредотачивайтесь только на том, что вы считаете решением, а давайте пойдем по этому пути с самого начала. Это проблема xy вы убеждены, что y решает x, но нам все еще не хватает полного понимания x. Попробуйте создать минимально воспроизводимый пример. Вам не обязательно показывать 40 различных запросов, даже не 5, но на самом деле показ кода для 2 очень поможет.

463035818_is_not_an_ai 28.05.2024 09:21

@ 463035818_is_not_an_ai Понятно, я сделаю прототип чего-нибудь в компилируемом проводнике. Дайте мне несколько минут, пожалуйста.

Eshy 28.05.2024 09:23

это общий симптом вопросов, направленных на то, чтобы избежать написания кода. Вы не показываете нам код, написания которого хотите избежать. Теперь представьте, что кто-то знает, как решить проблему, не написав код, которого вы хотите избежать. Для него не будет очевидно, о каком коде вы говорите, потому что он не стал бы его писать.

463035818_is_not_an_ai 28.05.2024 09:25

Судя по вашему описанию, я думаю, что было бы намного лучше использовать замену на основе словаря для индексации элементов, как в Pythonish "{a} {b}".format(a=1, b=1). И почему бы и нет BasicQuery("BLAH {} BLAH", "data");. Обратите внимание, что вы задаете вопрос XY. Вы специально спрашиваете о существовании рекурсии std::format, а не о том, как писать чистый код с использованием шаблонных запросов или чего-то подобного. Кроме того, очень сложно ответить, существует ли что-то в мире или нет — никто из моих знакомых не обладает такой силой.

KamilCuk 28.05.2024 09:25

Используйте литералы с фиксированными строками и помещайте в тип строку формата. Затем просто введите «стереть».

Red.Wave 28.05.2024 10:14
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
4
11
152
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Существует ли «рекурсивный» формат std::format?

Нет, нет. Вам придется написать его самостоятельно.


У меня есть возможность выбрать пять разных классов запросов или один шаблонный.

Рассмотрите возможность использования шаблонизатора.

Мой 1-минутный поиск https://www.google.com/search?q=C%2B%2B+templating+engine привел к Есть ли хороший шаблонизатор для C++ , https:/ /jinja2cpp.github.io/ и https://github.com/pantor/inja .

Другие вопросы по теме