2011-08-11 66 views
8

我真的很困惑,爲什麼我得到以下編譯錯誤。 Microsoft Visual Studio編譯器。錯誤C2678:二進制'=':找不到操作符,它需要類型'const std :: string'的左手操作數(或沒有可接受的轉換)

error C2678: binary '=' : no operator found which takes a left-hand operand of type 'const std::string' (or there is no acceptable conversion)

#include <stdio.h> 
#include <iostream> 
#include <sstream> 
#include <iterator> 

class MyException { 
public: 
    MyException( std::string message, 
         int line = 0) : m_message(message), 
             m_line(line) {} 
    const char* what() const throw(){ 
     if (m_line != 0) { 
      std::ostringstream custom_message; 
      custom_message << "Parsing Error occured at "; 
      custom_message << m_line << " Line : "; 
      custom_message << m_message;   
      m_message = custom_message.str(); 
     } 
     return m_message.c_str(); 
    } 
private: 
    std::string m_message; 
    int m_line; 
}; 
int main(int argc, char **argv) { 
    try { 
     // do something 
    }catch(MyException &e){ 
     std::cout << e.what(); 
    } 
} 

誤差在行 m_message = custom_message.str();

+4

你錯過頭'',這可能佔行爲。 – templatetypedef

回答

20

你聲明的方法爲const

const char* what() const throw(){ 

但你嘗試更改對象

m_message = custom_message.str(); 

,所以你得到一個錯誤。

你應該做的是在構造函數中構造自定義消息。

class MyException { 
public: 
    MyException(const std::string& message, int line = 0) : 
     m_message(message), m_line(line) { 
     if (m_line != 0) { 
      std::ostringstream custom_message; 
      custom_message << "Parsing Error occured at "; 
      custom_message << m_line << " Line : "; 
      custom_message << m_message;   
      m_message = custom_message.str(); 
     } 
    } 
    const char* what() const throw(){ 
     return m_message.c_str(); 
    } 
private: 
    std::string m_message; 
    int m_line; 
}; 

此外,我改變你的代碼,通過引用傳遞std :: string,這是通常的做法。

3

未來您正在嘗試將分配給MyException::m_message一個常量限定的方法MyException::what()內。在這樣的what()內部,整個*this對象被認爲是const,這意味着m_message成員也是const。由於std::string的賦值運算符需要左側的可修改對象(即非const對象),因此不能將任何對象分配給常量合格的std::string對象。您正在提供const之一。

如果你確實想要修改what()裏面的m_message,你應該聲明它是mutable類的成員(在這種情況下,它似乎是個好主意)。或者使用其他方法。

正如@john指出的那樣,在您的具體情況下,在構造函數中實際構建m_message而不是將其推遲到what()更有意義。我不明白爲什麼你每次打電話what()時都想重建你的m_message。除非您的m_line預計會以某種方式從一次呼叫改變爲what(),否則實際上並不需要每次都做。

1

除了其他答案;

您不包括<string>標頭,這可能是以後出現問題的原因。所用

東西給我弄了很多的是,一些std::頭包括其他,它允許你使用一個類,但也許只能用有限的功能,因爲std::頭,他們包括在所需要的最低限度爲該文件運行。這很煩人,因爲有時候你聲明瞭一個std::這樣的類,比如string,並且你沒有包含頭文件,定義將會很好,但其他一切可能會或可能不起作用 - 因爲定義工作正常。

0

請參閱what()函數的聲明,它被標記爲const(第二個const就行)。這意味着它不能改變任何成員變量,在你的情況下m_message字符串。這就是你得到錯誤的原因。

現在,你如何解決它?

您的代碼有誤,您的what()函數將在您每次調用what()函數時預先輸入"Parsing Error occured at "等文本。所以,與其這樣做,不必修改m_message成員,我建議你在類的構造函數格式化整個消息:

MyException(std::string message, int line = 0) 
{ 
    if (line != 0) 
    { 
     std::ostringstream custom_message; 
     custom_message << "Parsing Error occured at "; 
     custom_message << line << " Line : "; 
     custom_message << message;   
     m_message = custom_message.str();    
    } 
    else 
     m_message = message; 
} 
相關問題