Начальная идея
Глядя на источник , кажется, что вы можете использовать свой собственный распределитель, который затем используется внутренним потоком (internal_streambuf_t
) boost::format
. Это было бы достаточно для вашего случая?
Например, вы можете использовать что-то вроде libstdc ++ array_allocator
К сожалению boost::format
также использует пару std::vector
, которые не используют пользовательский распределитель, что может быть проблемой в вашем случае?
Как boost::format
работает
Я посмотрел на источник boost::format
, и вот как он работает (ниже описан str()
, <<
вызывает либо str()
или использует стандартные std::ostream
вещи):
- класс формата хранит все аргументы и строку формата отдельно, иногда используя пользовательский распределитель, иногда используя распределитель по умолчанию
- когда вызывается
str()
, он создает новый std::string
и делает его достаточно большим для результата, используя пользовательский распределитель
- затем добавляет все аргументы и фрагменты статической строки из строки формата в строку результата
- наконец возвращает строку результата по значению
Итак, итоговая строка результата не сохраняется внутри класса формата, а создается при необходимости.
Таким образом, даже если вы можете найти местоположение строки результата при использовании пользовательского распределителя, она доступна только после / во время вызова str()
.
Это должно объяснить, почему это невозможно: отформатированный результат никогда не сохраняется в «выходном буфере» в классе.
Почему это так работает
Почему они так поступили, я не знаю. Я думаю, это потому, что вы можете построить результат только после того, как все аргументы известны, это тратит пространство на хранение результата, и вам, вероятно, нужен только один раз для данной комбинации формат / аргумент. Поэтому создание его при необходимости не приводит к дополнительной работе, поскольку обычно str()
вызывается только один раз.
Решения
- Создайте оболочку вокруг
str()
или <<
и скопируйте результат в свой фиксированный буфер
- Используйте
stream_buffer
для потоковой передачи строки в буфер (см. Пример ниже)
- Унаследуйте класс и добавьте свою собственную функцию
str()
, которая сохраняет результат в фиксированном буфере.
Возможное решение с использованием boost :: iostreams (протестировано):
#include <iostream>
#include <boost/format.hpp>
#include <boost/iostreams/stream.hpp>
int main()
{
char buffer[100];
boost::iostreams::stream<boost::iostreams::array_sink>
stream(buffer, sizeof(buffer));
stream << (boost::format("arg1 = %1%") % 12.5);
stream << '\0'; // make sure buffer contains 0-terminated string
std::cout << buffer << std::endl;
}