我完成了我必须用C#样式打印的任务 的
tprintf("{} world{} {} {} {}\n","Hello",'!',123," Je", "end");
代码在
之下void tprintf(const char* format) // base function
{
std::cout << format;
}
template<typename T, typename... Targs>
void tprintf(const char* format, T value, Targs... Fargs)
{
for ( ; *format != '\0'; format++ ) {
if(*format == '{'){
if(format[1] == '}'){
std::cout << value;
tprintf(format+2, Fargs...); // recursive call
return;
}
}
std::cout << *format;
}
}
现在我必须做一些与众不同的事情:
tprintf("{1} {3} + {2} = {4} {1}.", "11", 7.5 , 4, 11.5);
输出:
的
11 4 + 7.5 = 11.5 11.
所以我认为这里简单的递归迭代比args dosent工作。我必须知道所有的功能。我想我应该做的是在开始时将所有args引入数组,然后在模式字符串中的正确位置输入它们。但是如何?
我做了这个
template<typename... Args> inline string pass(Args&&...) {return "End";}
template<typename T>
string some_function(T a){
std::ostringstream ostr;
ostr << a;
//cout<<ostr.str();
return ostr.str();
}
template<typename... Args> inline void expand(Args&&... args) {
string a="";
a.append(pass( some_function(args)... ))<<endl;
cout<<" result "<<a<<endl;
}
struct pass {
template<typename ...T> pass(T...) {}
};
但这只会返回“结束”。我意识到这个行为的原因与模板行为和递归有关。在递归中调用的最后一个想法是 模板内联字符串传递(Args&amp;&amp; ...){return“End”;}所以我扩展函数我只得到结束字符串不是一个字符串,包括解析为字符串的所有args。
所以我的问题是如何使这个功能正常工作
tprintf("{1} {3} + {2} = {4} {1}.", "", 7.5 , 4, 11.5);
答案 0 :(得分:0)
你最终会得到类似的东西:
a.append(pass("7.5"), pass("4"), pass("11.5"))
将“结束”附加到。
首先,很明显,cout不会在这里接受你的“数组”,即使你实际上给它一个数组。而且你需要逐个输出参数。所以你必须通过递归来提取每一个。
答案 1 :(得分:0)
您可以使用lambda函数。
template< typename ... args >
void tprintf( char const * fmt, args const & ... a ) {
std::array< std::function< void() >, sizeof ... (a) > fmt_fun
= { [&a]{ std::cout << a; } ... };
for ( ; * fmt; ++ fmt ) {
...
std::size_t fmt_n = * fmt - '0';
fmt_fun[ fmt_n ](); // print nth argument
...
}
}
请注意,不需要元编程风格的递归包迭代。
嗯,这个code works in Clang但在GCC中与longstanding bug发生冲突。