我想基于“ostream”创建一个类,它会执行一些自动格式化以生成逗号或制表符分隔值文件。我的想法是覆盖“operator<<”让它在每个值之前插入一个分隔符(除了行的开头和结尾),并在写入之前引用字符串。在最重要的“运营商<<”中方法,我想调用基类的方法,但我不能让它正常工作。
这是一个例子(用g ++ 4.3.3编译):
#include <iostream>
#include <ostream>
#include <string>
using namespace std;
class MyStream: public ostream
{
public:
MyStream(ostream& out): ostream(out.rdbuf()) {}
template <typename T> MyStream& operator<<(T value)
{
ostream::operator<<('+');
ostream::operator<<(value);
ostream::operator<<('+');
return *this;
}
};
template<> MyStream& MyStream::operator<< <string>(string value)
{
ostream::operator<<('*');
ostream::write(value.c_str(), value.size()); // ostream::operator<<(value);
ostream::operator<<('*');
return *this;
}
int main()
{
MyStream mystr(cout);
mystr << 10;
cout << endl;
mystr << "foo";
cout << endl;
mystr << string("test");
cout << endl;
return 0;
}
两个“运营商&lt;&lt;”方法(模板和特化)是以不同于其他方式处理字符串的方式。但是:
我做错了什么?非常感谢任何帮助。
答案 0 :(得分:5)
打印字符串和字符的operator<<
重载是自由函数。但是当您强制调用成员函数时,您将强制它们转换为ostream
中声明的成员函数的一个候选者。对于'*'
,它可能会使用int
重载,对于"foo"
,它可能会使用const void*
重载。
我不会继承ostream
,而是将ostream
存储为参考成员,然后从operator<<
委托给它。我也不会让operator<<
成为一个成员,而是一个免费的功能模板,而不是专门的,但会使operator<<
和std::string
的{{1}}重载。
答案 1 :(得分:2)
以下内容可能有效:
#include <ostream>
#include <string>
using namespace std;
class MyStream: public ostream
{
public:
MyStream(ostream& out): ostream(out.rdbuf()) {}
template <typename T> MyStream& operator<<(const T& value)
{
(ostream&)*this << '+' << value << '+';
return *this;
}
MyStream& operator<< (const string& value)
{
(ostream&)*this << '*' << value << '*';
return *this;
}
MyStream& operator<< (const char* cstr)
{
(ostream&)*this << '(' << cstr << ')';
return *this;
}
};