Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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

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

like image 209
Avinash Avatar asked Aug 11 '11 06:08

Avinash


2 Answers

You declare the method as 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.

like image 71
john Avatar answered Oct 09 '22 03:10

john


You are trying to assign to MyException::m_message inside a const-qualified method MyException::what(). Inside such what() the entire *this object is considered to be const, which means that m_message member is also const. You can't assign anything to a const-qualified std::string object, 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 const one.

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

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

like image 35
AnT Avatar answered Oct 09 '22 04:10

AnT