0

我正在尝试在 ostringstream 实例上创建一个瘦包装器,它将所有插入操作委托给封闭的 ostringstream 实例。这个想法是在进行级联插入操作时保留类型。通常,级联插入操作的结果类型是 ostream&,并且任何原始类型都会丢失。我想维护表达式的类型,因为我希望能够将它传递给一个方法以进行进一步处理,并且希望能够访问底层的 ostringstream 以获取插入的字符串数据。

我希望能够执行以下操作,并将表达式的结果设为 LgStream:

LgStream() << 26 << " a plain string " << std::string("a std string") << someObjWithItsOwnInsertionOperator;

因此,我为基本类型定义了 operator<<(),并将模板方法定义为其他所有内容的包罗万象:

class LgStream
{
public:
    ostringstream m_oss;
    string str() {return m_oss.str();}

    LgStream &operator<<(int x) {m_oss << x; return *this;}
    LgStream &operator<<(long x) {m_oss << x; return *this;}
    LgStream &operator<<(char x) {m_oss << x; return *this;}
    LgStream &operator<<(bool x) {m_oss << (x ? 'T':'F'); return *this;}
    LgStream &operator<<(double x) {m_oss << x; return *this;}

    template <typename T>
    LgStream &operator<<(const T &x) {m_oss << x; return *this;}
    template <typename T>
    LgStream &operator<<(const T x) {m_oss << x; return *this;}

};

我没有正确,并且收到“模棱两可的过载”错误。例如:

LgStream() << "This is a plain string";

error: ambiguous overload for 'operator<<' in 'LgStream() << "This is a plain string"'
note: candidates are:
note: LgStream& LgStream::operator<<(int) <near match>
note:   no known conversion for argument 1 from 'const char [23]' to 'int' 
note: LgStream& LgStream::operator<<(long int) <near match>
note:   no known conversion for argument 1 from 'const char [23]' to 'long int'
note: LgStream& LgStream::operator<<(char) <near match>
note:   no known conversion for argument 1 from 'const char [23]' to 'char'

note: LgStream& LgStream::operator<<(bool)
note: LgStream& LgStream::operator<<(std::string)
note: LgStream& LgStream::operator<<(const T&) [with T = char [23], LgStream = LgStream]
note: LgStream& LgStream::operator<<(T) [with T = const char*, LgStream = LgStream]

任何一种语法都可以得到任何帮助,或者如果我采用了错误的方法。

4

2 回答 2

0

歧义的主要来源来自两个模板函数。一个取“const T &x”,另一个取“const T x”。任何 const T 值也适用于参考版本。摆脱其中之一。在删除“operator<<(const T x)”的定义后,我在 VC++ 中编译了这段代码,并且编译没有错误。也许您的编译器也会这样做。

于 2013-01-28T08:38:15.860 回答
0

你为什么不从 std::basic_ostringstream 派生你的类?这样您就不必定义自己的插入运算符,并且可以使用所有标准的插入运算符。

参考资料会说从 STL 类派生是危险的,最好避免。AFAIK,如果您要通过引用其基类来多态地使用派生类,这只是一个问题。解释一下,由于没有一个 STL 类将其 dtor 声明为虚拟,因此销毁多态对象指针不会调用派生类 dtor,并且可能导致内存泄漏。只要你不这样使用LgStream,你应该没问题。

于 2013-01-28T06:25:49.023 回答