[英]boost::format with variadic template arguments
假设我有一个类似printf
的函数(用于记录)利用完美转发:
template<typename... Arguments>
void awesome_printf(std::string const& fmt, Arguments&&... args)
{
boost::format f(fmt);
f % /* How to specify `args` here? */;
BlackBoxLogFunction(boost::str(f).c_str());
}
(我没有编译这个,但我的实际功能遵循这个指导原则)
如何将variadic参数“展开”到boost :: format变量f
?
与可变参数模板一样,您可以使用递归:
std::string awesome_printf_helper(boost::format& f){
return boost::str(f);
}
template<class T, class... Args>
std::string awesome_printf_helper(boost::format& f, T&& t, Args&&... args){
return awesome_printf_helper(f % std::forward<T>(t), std::forward<Args>(args)...);
}
template<typename... Arguments>
void awesome_printf(std::string const& fmt, Arguments&&... args)
{
boost::format f(fmt);
auto result = awesome_printf_helper(f, std::forward<Arguments>(args)...);
// call BlackBoxLogFunction with result as appropriate, e.g.
std::cout << result;
}
演示 。
在C ++ 17中,简单地说(f % ... % std::forward<Arguments>(args));
会做。
我做了一些谷歌搜索,并找到了一个有趣的解决方案:
#include <iostream>
#include <boost/format.hpp>
template<typename... Arguments>
void format_vargs(std::string const& fmt, Arguments&&... args)
{
boost::format f(fmt);
int unroll[] {0, (f % std::forward<Arguments>(args), 0)...};
static_cast<void>(unroll);
std::cout << boost::str(f);
}
int main()
{
format_vargs("%s %d %d", "Test", 1, 2);
}
我不知道这是否是推荐的解决方案,但似乎有效。 我不喜欢hacky static_cast
用法,这似乎有必要使GCC上未使用的变量警告静音。
总结一下void.pointer的解决方案以及Praetorian , TC和Jarod42提出的提示,让我提供最终版本( 在线演示 )
#include <boost/format.hpp>
#include <iostream>
template<typename... Arguments>
std::string FormatArgs(const std::string& fmt, const Arguments&... args)
{
boost::format f(fmt);
std::initializer_list<char> {(static_cast<void>(
f % args
), char{}) ...};
return boost::str(f);
}
int main()
{
std::cout << FormatArgs("no args\n"); // "no args"
std::cout << FormatArgs("%s; %s; %s;\n", 123, 4.3, "foo"); // 123; 4.3; foo;
std::cout << FormatArgs("%2% %1% %2%\n", 1, 12); // 12 1 12
}
另外, 正如TC所指出的那样 ,使用自C ++ 17以来可用的fold表达式语法,可以用更简洁的方式重写FormatArgs函数
template<typename... Arguments>
std::string FormatArgs(const std::string& fmt, const Arguments&... args)
{
return boost::str((boost::format(fmt) % ... % args));
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.