正确的模板方法来包装ostream

时间:2014-09-02 03:04:50

标签: c++ ostream

给出一个班级

class ostreamWrapper
{
    private:
        ostream * str;

    public:
        ostreamWrapper operator << (const char *);
}

其中ostream * str将指向std :: cout,ostreamWrapper operator << (const char *)将给定文本发送到包装的ostream str

在这种情况下,我只能instance << "const char * text"而没有其他可打印数据。与直接<< std :: cout或std :: cerr。

不同

如何实现operator方法,以便接受任何类型的数据,就像std :: cout或std :: cerr直接做的那样?

2 个答案:

答案 0 :(得分:5)

首先,编写一个公开的operator<<模板,以便它可以接受任何类型,只需将其转发到已包装的ostream

template <class T>
ostreamWrapper& operator<<(T&& x) {
    *str << std::forward<T>(x);
    return *this;
}

其次,为了接受std::endl等流操纵器模板的插入,添加第二个公开operator<<,专门接受用于包裹ostream的操纵器:

ostreamWrapper& operator<<(ostream& (*manip)(ostream&)) {
    *str << manip;
    return *this;
}

省略第二次重载将导致重载的操纵器或操纵器模板插入失败并出现“模糊过载”或类似的错误消息。

答案 1 :(得分:2)

查看建议实现的示例,它会推导出模板参数类型并相应打印,如果可以使用C ++ 11,请参阅@Brian答案:

#include <iostream>

using namespace std;

class ostreamWrapper {
private:
    ostream* str;

public:
    ostreamWrapper(ostream* str_v) : str(str_v) {}

    template <typename T>
    ostreamWrapper& operator<<(const T& t) {
        if (str)
            *str << t;
        return *this;
    }
};

int main() {
    ostreamWrapper osw(&std::cout);
    osw << 1 << " texto " << std::string(" otro texto ") << 1.2345;
    return 0;
}