c++ - 在 C++ 中使用可变参数模板迭代参数包

标签 c++ c++11 variadic-templates

作为日志库的一部分,我希望能够迭代参数包,将每个值写入流。然而,我的第一次尝试没有编译。第一个错误是“错误 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;
}

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

最佳答案

递归是一种选择:

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)...);
}

Demo .

或者,包扩展技巧仍然有效,稍作调整 - 您需要对列表中的第一项进行特殊处理:

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;
}

Demo .

关于c++ - 在 C++ 中使用可变参数模板迭代参数包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26550065/

相关文章:

c++ - 多态性中的通用 STL 迭代器

c++ - 如何确定它是强制转换还是构造函数调用

c++ - 带有 C++11 的 Visual Studio 2008

c++ - 检查可变参数模板参数的唯一性2

c++ - 选择可变参数模板最后一个参数的有效方法

c++ - 自定义语言中 C++ 的 C-Wrapper DLL 的性能

C++自省(introspection)技术,类似于python

c++ - 从类内部线程化成员函数

c++ - 如何以循环方式迭代 std::bitset 并返回下一个 'true' 位的索引?

c++ - 提取类的模板参数并迭代它们的最紧凑的方法是什么?