使用c ++ variadic模板打印

时间:2013-06-08 09:16:31

标签: c++ loops printf variadic-templates

我完成了我必须用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);

2 个答案:

答案 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发生冲突。