【问题标题】:error C2678: binary '=' : no operator found which takes a left-hand operand of type 'const std::string' (or there is no acceptable conversion)错误 C2678:二进制“=”:未找到采用“const std::string”类型的左操作数的运算符(或没有可接受的转换)
【发布时间】:2011-08-11 06:20:23
【问题描述】:

我真的很困惑为什么会出现以下编译错误。 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();

【问题讨论】:

  • 您缺少标题 &lt;string&gt;,这可能是导致该行为的原因。

标签: c++ visual-studio


【解决方案1】:

您将方法声明为 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,这是通常的做法。

【讨论】:

    【解决方案2】:

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

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

    正如@john 所指出的,在您的特定情况下,在构造函数中实际构建m_message 而不是将其推迟到what() 更有意义。我真的不明白为什么你每次打电话给what() 时都想重建你的m_message。除非您的 m_line 预计会以某种方式从一个呼叫更改为 what() 到另一个呼叫,否则真的没有必要每次都这样做。

    【讨论】:

      【解决方案3】:

      除了其他答案;

      您没有包含 &lt;string&gt; 标头,这可能是以后出现问题的原因。

      让我印象深刻的是一些std:: 标头包含其他标头,这允许您使用一个类,但可能仅具有有限的功能,因为它们包含的std:: 标头是裸露的该文件运行所需的最小值。这很烦人,因为有时您声明了一个 std:: 类,例如 string 并且您没有包含标题,定义会很好,但其他一切可能会或可能不会工作 - 导致您进行大量调试,因为定义运行良好。

      【讨论】:

        【解决方案4】:

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

        现在,你如何解决它?

        您的代码错误,您的what() 函数将在您每次调用what() 函数时预先添加"Parsing Error occured at " 等文本。所以,与其修改m_message 成员,我建议您在类的ctor 中格式化整个消息:

        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;
        }
        

        【讨论】:

          猜你喜欢
          • 2015-11-18
          • 2014-12-04
          • 1970-01-01
          • 2011-12-09
          • 1970-01-01
          • 2017-03-17
          • 1970-01-01
          • 1970-01-01
          • 2012-07-23
          相关资源
          最近更新 更多