c++ - C++ 中可变参数模板对的打印方法

标签 c++ templates cout variadic parameter-pack

我想实现这样的目标:

export_vars("path/to/file.dat", {"variable_name", obj}, {"another_variable", 2});

哪里obj可以是任何类型,只要它有 <<重载 - 想法是写入 ofstream稍后的。我试过(一对 initializer_list):

void
export_vars(const std::string& path, std::initializer_list<std::pair<std::string, std::any>> args)
{       
    for (auto& [name, var] : args)
        std::cout << name << ": " << var << std::endl;
}

但是std::any不能是 <<不知道底层类型。可以使用可变参数模板和参数包扩展来实现吗?我也试过类似的东西:

template <class... Args>
void
export_vars(const std::string& path, Args... args)
{   
    (std::cout << ... << args.first << args.second) << std::endl;
}

但这显然是错误的。有什么建议吗?

最佳答案

{..} 没有类型,因此不允许大多数推导。

几个解决方法:

  • 显式更改调用以使用 std::pair:

    template <typename ... Pairs>
    void export_vars(const std::string&, const Pairs&... args)
    {       
        ((std::cout << args.first << ": " << args.second << std::endl), ...);
    }
    
    int main()
    {
        export_vars("unused", std::pair{"int", 42}, std::pair{"cstring", "toto"});
    }
    

    Demo

  • 不要使用模板:

    void export_vars(const std::string&,
                     const std::initializer_list<std::pair<std::string, Streamable>>& args)
    {
        for (const auto& [name, value] : args) {
            std::cout << name << ": " << value << std::endl;
        }
    }
    int main()
    {
        export_vars("unused", {{"int", 42}, {"cstring", "toto"}});
    }
    

    Streamable 使用类型删除,可能是这样的:

    class Streamable
    {
        struct IStreamable
        {
            virtual ~IStreamable() = default;
            virtual void print(std::ostream&) = 0;
        };
    
        template <typename T>
        struct StreamableT : IStreamable
        {
            StreamableT(T t) : data(std::forward<T>(t)) {}
            virtual void print(std::ostream& os) { os << data; }
    
            T data;
        };
    
        std::unique_ptr<IStreamable> ptr;
    public:
        template <typename T>
        // Possibly some concepts/SFINAE as requires(is_streamable<T>)
        Streamable(T&& t) : ptr{std::make_unique<StreamableT<std::decay_t<T>>>(t)} {}
    
        friend std::ostream& operator << (std::ostream& os, const Streamable& streamable)
        {
            streamable.ptr->print(os);
            return os;
        } 
    };
    

    Demo

关于c++ - C++ 中可变参数模板对的打印方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70155255/

相关文章:

c++ - Qt 小部件内存管理

c++ - 重写采用继承结构的函数

templates - 检查类成员是否是静态的

c++ - 当包含方括号时,默认构造函数不会在模板类中编译 (g++4.6.1)

c++ - 检查哪些输出写入了标准输出

C++ | cout, 打印返回的对象

c++ - 使用仿函数作为谓词的 C++ STL 程序

C++询问用户输入是否正确错误

C++模板检查类型验证

c++ - 简单程序中的无数错误