我真的很困惑为什么我会遇到编译错误。 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();
答案 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;
}