Thực hiện chức năng chuỗi định dạng giống như Python với C++ 11 mẫu regex và variadic.
/**
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;
}
Ví dụ: cpp.sh/6nli
Có gì sai với tốt cũ C/K & R xxprintf()? – FoggyDay
Tôi thích nó nói chung nhưng nó không thể chấp nhận 'chuỗi' trực tiếp, đó là gây phiền nhiễu. Tôi thích một phương thức không yêu cầu tôi gọi '.c_str()' trên tất cả các chuỗi của tôi. Thêm vào đó, nó là hư không gần như là tốt đẹp như của Python 'định dạng() '. –
@FoggyDay: Không có loại an toàn. Ở tất cả. Không thể mở rộng. –