С++ 11 Эквивалент Boost.Format
Что-нибудь вроде Boost.Format в стандарте С++ 11? Мне удалось избежать использования Boost с лучшим вариантом С++ 11 для всех остальных, которые у меня были.
В этом случае Boost.Format не содержит свечи для синтаксиса Python format()
. Что-то вроде этого было бы еще лучше.
Ответы
Ответ 1
Есть предложение для чего-то похожего на форсированный формат. Тем не менее, он не является частью С++ 11 или С++ 14, и не имеет никакого отношения к форматированию строк.
Здесь вы можете найти последнее предложение. В отличие от форсированного формата, он основан на вариативных шаблонах.
Ответ 2
Как правильно указано nosid, ни С++ 11, ни С++ 14 не дают эквивалента Boost Format.
Однако библиотека fmt, которая необязательно использует функции С++ 11, такие как вариативные шаблоны, обеспечивает реализацию функции format
, подобной Python:
std::string s = fmt::format("I'd rather be {1} than {0}.", "right", "happy");
и безопасные альтернативы функциям *printf
:
fmt::printf("The answer is %d\n", 42);
Отказ от ответственности. Я являюсь автором этой библиотеки
Ответ 3
Реализация строки строки в стиле Python с регулярными выражениями и переменными шаблонами С++ 11.
/**
Helper code to unpack variadic arguments
*/
namespace internal
{
template<typename T>
void unpack(std::vector<std::string> &vbuf, T t)
{
std::stringstream buf;
buf << t;
vbuf.push_back(buf.str());
}
template<typename T, typename ...Args>
void unpack(std::vector<std::string> &vbuf, T t, Args &&... args)
{
std::stringstream buf;
buf << t;
vbuf.push_back(buf.str());
unpack(vbuf, std::forward<Args>(args)...);
}
}
/**
Python-like string formatting
*/
template<typename ... Args>
std::string format(const std::string& fmt, Args ... args)
{
std::vector<std::string> vbuf; // store arguments as strings
std::string in(fmt), out; // unformatted and formatted strings
std::regex re_arg("\\{\\b\\d+\\b\\}"); // search for {0}, {1}, ...
std::regex re_idx("\\b\\d+\\b"); // search for 0, 1, ...
std::smatch m_arg, m_idx; // store matches
size_t idx = 0; // index of argument inside {...}
// Unpack arguments and store them in vbuf
internal::unpack(vbuf, std::forward<Args>(args)...);
// Replace all {x} with vbuf[x]
while (std::regex_search(in, m_arg, re_arg)) {
out += m_arg.prefix();
if (std::regex_search(m_arg[0].str(), m_idx, re_idx)) {
idx = std::stoi(m_idx[0].str());
}
if(idx < vbuf.size()) {
out += std::regex_replace(m_arg[0].str(), re_arg, vbuf[idx]);
}
in = m_arg.suffix();
}
out += in;
return out;
}
Пример: cpp.sh/6nli