简体   繁体   English

如何在 std::ostream 上对我的打印 function 进行模板化?

[英]How can I template my print function on std::ostream?

So far, I have a function print:到目前为止,我有一个 function 打印:

template < char Sep = ' ', class... Args >
void print(Args&&... args)
{
    ([](Args&& arg)
        {
            std::cout << arg << Sep;
        }(std::forward<Args>(args)), ...);

    std::cout << '\n';
}

int main()
{
    print("a", 'b', 3, 4.0, 5.0f, true);
}

I want to template it on std::ostream so that I can print to the buffer I want but I am struglling.我想在 std::ostream 上对其进行模板化,以便可以打印到我想要的缓冲区,但我很挣扎。 Here is what I tried (I have put errors as comment in the code):这是我尝试过的(我在代码中将错误作为注释):

//Error: a nontype parameter may not have class type
template < std::ostream os, char Sep = ' ', class... Args >
void print(Args&&... args){ /*omitted code */ os << arg << Sep; }

int main()
{
    print("a", 'b', 3, 4.0, 5.0f, true);
}

I though maybe I could use a class to work-around the problem:我虽然也许我可以使用 class 来解决这个问题:

template < class Buffer >
class Printer
{
public:
    void Set(Buffer* buff)
    {
        this->buff = buff;
    }

    //Error: the usage of 'Printer<std::ostream>::buff' requires the compiler
    //to capture this but the current default capture mode does not allow it
    template < char Sep = ' ', class... Args >
    void operator()(Args&&... args)
    {
        ([](Args&& arg)
            {
                (*buff) << arg << Sep;
            }(std::forward<Args>(args)), ...);

        std::cout << '\n';
    }

private:
    Buffer* buff;
};

int main()
{
    Printer<std::ostream> print;
    print.Set(&std::cout);
    print("a", 'b', 3, 4.0, 5.0f, true);
}

Use an ordinary template argument and pass the stream as parameter to the function:使用普通模板参数并将 stream 作为参数传递给 function:

#include <iostream>


template <typename stream, char Sep = ' ', class... Args >
void print(stream& out,Args&&... args)
{
    ([&out](Args&& arg)
        {
            out << arg << Sep;
        }(std::forward<Args>(args)), ...);

    std::cout << '\n';
}

int main()
{
    print(std::cout,"a", 'b', 3, 4.0, 5.0f, true);
}

If only std::ostream s are ok you need not make it a template, but simply use an std::ostream& argument.如果只有std::ostream可以,则无需将其设为模板,只需使用std::ostream&参数即可。 The standard library makes use of inheritance only sparingly, but for streams there are base classes that can be used when you want to use standard streams.标准库仅少量使用 inheritance,但对于流,当您想要使用标准流时可以使用基类。


PS: As pointed out by MarekR you do not need the lambda. PS:正如 MarekR 所指出的,您不需要 lambda。 The function is simpler like this: function 更简单,如下所示:

#include <iostream>


template <typename stream, char Sep = ' ', class... Args >
stream& print(stream& out,Args&&... args)
{
    return ((out << args << Sep) , ...) << '\n';
}

int main()
{
    print(std::cout,"a", 'b', 3, 4.0, 5.0f, true);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM