在类中包装ostream并模板化<<操作符

时间:2018-09-13 08:25:55

标签: c++ c++11 templates iostream

我想将C ++流包装在模板类中,以使为流定义的所有<<操作对于包装类都已经可用。

您可以更改以下代码,使其编译时不会过多改变总体意图吗?

#include <iostream>
class Foo
{
private:

    std::ostream& os;

public:

    explicit Foo( std::ostream& os ) : os( os ) {};

    template<class T>
    Foo& operator<<( const T& t )
    {
        os << t << '!';
        return *this;
    }

};

int main()
{

    Foo( std::cout ) << "test" << '\n'; // works fine 
    Foo( std::cout ) << "test" << std::endl; // compilation error

    return 0;
}

我假设std :: endl具有某种类型,因此被模板化方法“捕获”。

2 个答案:

答案 0 :(得分:0)

如kmdreko所建议,您需要为模板函数添加重载

(std :: endl是模板函数,不是类或简单类型)

喜欢这个:

#include <iostream>
class Foo
{
private:

    std::ostream& os;

public:

    explicit Foo(std::ostream& os) : os(os) {};

    // for classes
    template<class T>
    Foo& operator<<(const T& t)
    {
        os << t << '!';
        return *this;
    }

    // for endl
    Foo& operator<<(std::ostream& (*pf) (std::ostream&)) {
        os << pf;
        return *this;
    }
};

答案 1 :(得分:0)

您可能应该用SFINAE来保护它,并完美地论证。

    template<class T> auto operator<<(T &&t)
         -> decltype(os << std::forward<T>(t) << '!', *this)
    {
            return os << std::forward<T>(t) << '!', *this;
    }

现在,它应该接受std::ostream可以打印的所有参数,并且无法与其他所有参数一起编译。