跨级联插入操作保留类型

时间:2013-01-28 06:06:20

标签: c++ operator-overloading insertion ambiguous

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

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

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

所以我为基本类型定义了运算符&lt;&lt;(),并为其他所有内容定义了模板方法:

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]

任何帮助都可以使用任何语法,或者我采取错误的方法。

2 个答案:

答案 0 :(得分:0)

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

参考文献会说从STL课程中获取是危险的,并且最好避免使用它。 AFAIK,如果您通过引用其基类以多态方式使用派生类,这只是一个问题。为了解释,由于没有一个STL类声明它们的dtors是虚拟的,因此销毁多态对象指针不会调用派生类dtor并导致内存泄漏。只要你不以这种方式使用LgStream,你应该没问题。

答案 1 :(得分:0)

模糊性的主要来源是两个模板函数。一个采用“const T&amp; x”,另一个采用“const T x”。任何const T值也都有资格获得参考版本。摆脱其中一个。在删除“operator&lt;&lt;(const T x)”的定义后,我在VC ++中编译了这段代码,并且编译时没有错误。也许你的编译器也会这样做。