Reputation: 13277
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();
Upvotes: 10
Views: 29846
Reputation: 18268
See the declaration of the what()
function, it is marked const
(the second const
on the line). That means that it cannot alter any member variables, in your case the m_message
string. That is why you get the error.
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_message
member, I suggest that you format the entire message in the ctor of the class:
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;
}
Upvotes: 0
Reputation: 320797
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.
Upvotes: 3
Reputation: 88092
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.
Upvotes: 22
Reputation: 3873
In addition to the other answers;
You're not including the <string>
header, which may be the cause of a problem later.
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 minimum that is needed for that file to run. This is quite an annoyance because sometimes you declare a std::
class such as string
and 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.
Upvotes: 1