C++ 错误 C2678:二进制“=”:未找到采用“const std::string”类型的左侧操作数的运算符(或没有可接受的转换)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7021624/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 16:22:39  来源:igfitidea点击:

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

c++visual-studio

提问by Avinash

I am really confused on why I am getting following compilation error. Microsoft Visual Studio Compiler.

我真的很困惑为什么我会遇到编译错误。微软 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)

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

Error is coming at line m_message = custom_message.str();

错误即将上线 m_message = custom_message.str();

回答by john

You declare the method as const

您将该方法声明为 const

const char* what() const throw(){

but then you try to change the object

但随后您尝试更改对象

m_message = custom_message.str();

so you get an error.

所以你会得到一个错误。

What you should do instead is construct the custom message in the constructor.

您应该做的是在构造函数中构造自定义消息。

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

Also I changed your code to pass the std::string by reference, which is usual practice.

我还更改了您的代码以通过引用传递 std::string,这是通常的做法。

回答by AnT

You are trying to assign to MyException::m_messageinside a const-qualified method MyException::what(). Inside such what()the entire *thisobject is considered to be const, which means that m_messagemember is also const. You can't assign anything to a const-qualified std::stringobject, since std::string's assignment operator requires a modifiable (i.e. a non-const one) object on the left-hand side. You are supplying a constone.

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

If you really want to be able to modify the m_messageinside what(), you should declare it as mutablemember of the class (in this case it appears to be a good idea). Or use some other approach.

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

As @john noted, in your specific case it makes more sense to actually build m_messagein constructor instead of postponing it till what(). I don't really understand why you'd even want to rebuild your m_messageevery time you call what(). Unless your m_lineis expected to change somehow from one call to what()to another, there's really no need to do it every time.

正如@john 指出的那样,在您的特定情况下,实际构建m_message构造函数而不是将其推迟到what(). 我真的不明白为什么你m_message每次调用what(). 除非您m_line希望以某种方式从一个调用更改what()为另一个调用,否则真的没有必要每次都这样做。

回答by Seb Holzapfel

In addition to the other answers;

除了其他答案;

You're not including the <string>header, which may be the cause of a problem later.

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

Something that used to get me a lot is that some std::headers include others, which allows you to use a class, but maybe only with limited functionality because the std::headers that they include are the bare minimumthat is needed for that file to run. This is quite an annoyance because sometimes you declare a std::class such as stringand you haven't included the header, the definition will be fine but everything else may or may not work - leading you to a lot of debugging because the definition worked fine.

曾经让我受益匪浅的是,某些std::标头包含其他标头,这允许您使用一个类,但可能功能有限,因为std::它们包含的标头是该文件运行所需的最低限度。这很烦人,因为有时您声明了一个std::类,例如string并且您没有包含标题,定义会很好,但其他一切可能会或可能不会工作 - 导致您进行大量调试,因为定义工作正常。

回答by wilx

See the declaration of the what()function, it is marked const(the second conston the line). That means that it cannot alter any member variables, in your case the m_messagestring. That is why you get the error.

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

Now, how do you fix it?

现在,你如何解决它?

Your code is wrong, your what()function will prepend the "Parsing Error occured at "etc. text each time you invoke the what()function. So, instead of doing that having to modify the m_messagemember, I suggest that you format the entire message in the ctor of the class:

您的代码是错误的,每次调用该函数时,您的what()函数都会在前面加上"Parsing Error occured at "etc. 文本what()。因此,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;
}