2012-08-07 76 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