2012-08-07 80 views
5

能否请你帮我在下面的代码中发现的问题 (代码类似于C++ stream as a parameter when overloading operator<<):“错误:不对应的“操作符<<”用的std :: string工作时

#include <iostream> 
#include <string> 

class logger 
{ 
    public: 
    void init(std::ostream& ostr) 
    { 
     stream = &ostr; 
    } 

    template< typename t > 
    logger& operator <<(t& data) 
    { 
     *stream << data; 
     return *this; 
    } 

    logger& operator <<(std::ostream& (*manip)(std::ostream &)) 
    { 
     manip(*stream); 
     return *this; 
    } 

    logger& operator <<(std::ios_base& (*manip)(std::ios_base&)) 
    { 
     manip(*stream); 
     return *this; 
    } 

    private: 
    std::ostream* stream; 
}; 

int main(int argc, char* argv[]) 
{ 
    logger log; 
    log.init(std::cout); 
    log << "Hello" << std::endl; 
    //log << std::string("world") << std::endl; 

    return 0; 
} 

一切工作正常,直到我取消注释包含“世界”的行。在这种情况下,海湾合作委员会产生 错误:'运营商< <'不匹配... ...

有趣的是,VS2008没有这个代码的问题。

谢谢!

+0

Visual Studio做了许多其他编译器不会做的类型转换。尝试std :: string(“world”).c_str(); – steveg89 2012-08-07 17:35:08

回答

12

std::string("world")创建一个不能绑定到非const引用的临时值。添加常量的参数:

template< typename t > 
logger& operator <<(t const& data) 
{ 
    *stream << data; 
    return *this; 
} 

编辑:只是注意到你提到这个工程在MSVS。这是因为MS语言扩展,它可以关闭,它也会显示错误。每当我使用MSVS,我关闭语言扩展。

+2

MSVC已经扩展了C++,以便能够创建非''contst'引用。这解释了编译器之间的差异。可以通过编译器选项来禁用此功能,但是有很多MS头文件无法工作。 – 2012-08-07 17:36:37

+0

@MagnusHoff我甚至没有注意到这个部分,但你是对的。我讨厌那些扩展。 – 2012-08-07 17:39:10