使用c ++中的可变参数模板迭代参数包

Rob*_*son 4 c++ variadic-templates c++11

作为日志库的一部分,我希望能够迭代参数包,将每个值写入流.然而,我的第一次尝试不能编译.第一个错误是"错误C2144:语法错误:'int'应该以'}'开头".

#include <sstream>
#include <ostream>
#include <iomanip>
#include <fstream>

template <typename ...Args>
std::ostream & Write(std::ostream & o, std::initializer_list<Args...> list) 
{
    size_t size = list.size();

    if(list.size() > 0)
    {
        for(size_t i = 0; i < (size - 1); i++)
            o << list[i] << ", ";

        o << list[i];
    }

    return o;
}

template<typename ...Args>
std::ostream & Write(std::ostream & o, Args...)
{
    return Write(o, { Args... });
}

int main(int argc, wchar_t * argv[])
{
    std::ostringstream o;

    Write(o, 1, "Hello", 2, "World", 3, 1.4857);

    // o should contain the string of characters "1, Hello, 2, World, 3, 1.4857"

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

如何迭代...中的每个项目并将其发送到流?

T.C*_*.C. 7

递归是一种选择:

template<typename Arg>
std::ostream & Write(std::ostream & o, Arg&& arg) { 
    return o << std::forward<Arg>(arg); 
}

template<typename Arg, typename ...Args>
std::ostream & Write(std::ostream & o, Arg&& arg, Args&&... args)
{
    o << std::forward<Arg>(arg) << ", ";
    return Write(o, std::forward<Args>(args)...);
}
Run Code Online (Sandbox Code Playgroud)

演示.

或者,包扩展技巧仍然有效,只需稍加调整 - 您需要特殊情况下列表中的第一项:

template<typename Arg, typename ...Args>
std::ostream & Write(std::ostream & o, Arg&& arg, Args&&... args)
{
    o << std::forward<Arg>(arg);

    using expander = int[];
    (void) expander{ (o << ", " << std::forward<Args>(args), void(), 0)... };

    return o;
}
Run Code Online (Sandbox Code Playgroud)

演示.