错误C2678:binary'=':找不到运算符,它接受类型为'const std :: string'的左手操作数(或者没有可接受的转换)

时间:2011-08-11 06:20:24

标签: c++ visual-studio

我真的很困惑为什么我会遇到编译错误。 Microsoft Visual Studio编译器。

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 个答案:

答案 0 :(得分: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,这是通常的做法。

答案 1 :(得分:3)

您正尝试在const限定方法MyException::m_message内分配MyException::what()。在此类what()内,整个*this对象被视为const,这意味着m_message成员也是const。您不能将任何内容分配给const限定的std::string对象,因为std::string的赋值运算符需要左侧的可修改(即非常量)对象。您正在提供const个。

如果您真的希望能够修改m_message内的what(),则应将其声明为该类的mutable成员(在这种情况下,它似乎是一个好主意)。或者使用其他方法。

正如@john所指出的,在你的具体情况下,在构造函数中实际构建m_message而不是将其推迟到what()更有意义。我真的不明白你每次打电话m_message时甚至想要重建what()的原因。除非您的m_line预计会以某种方式从一个what()调用到另一个调用,否则每次都不需要这样做。

答案 2 :(得分:1)

除了其他答案;

您未包含<string>标题,这可能是以后出现问题的原因。

过去常常让我感到困惑的是,有些std::标题包含其他标题,允许您使用某个类,但可能只有功能有限,因为它们包含的std::标题是该文件运行所需的最低。这是一个非常烦人的事情,因为有时你宣布一个std::类,如string并且你没有包含标题,定义会很好,但其他一切可能会或可能不起作用 - 引导你到很多调试因为定义工作正常。

答案 3 :(得分:0)

请参阅what()函数的声明,它标记为const(行上的第二个const)。这意味着它不能改变任何成员变量,在您的情况下是m_message字符串。这就是你得到错误的原因。

现在,你如何解决它?

您的代码错误,每次调用what()函数时,"Parsing Error occured at "函数都会添加what()等文本。因此,我建议您在课程的代码中格式化整个消息,而不是必须修改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;
}