operator overloading Error: cannot bind non-const lvalue reference of type ‘some-type’ to an rvalue of type ‘some-type’
operator overloading Error: cannot bind non-const lvalue reference of type ‘some-type’ to an rvalue of type ‘some-type’
#include <iostream>
#include <string>
using namespace std;
namespace ComplexNumberNamespace
{
typedef struct _Data
{
double real;
double imag;
}Data;
class ComplexNumber
{
private:
Data data{};
public:
ComplexNumber();
ComplexNumber(float real, float imag);
ComplexNumber(ComplexNumber&);
string to_string();
void operator = (ComplexNumber&);
ComplexNumber operator + (ComplexNumber& rhs);
};
string ComplexNumber::to_string() {
std::string str;
str = std::to_string(data.real);
str.append(" + i ");
str.append(std::to_string(data.imag));
return str;
}
ComplexNumber::ComplexNumber(ComplexNumber & rhs) {
std::cout<<"copy constructor";
data.real = rhs.data.real;
data.imag = rhs.data.imag;
}
ComplexNumber::ComplexNumber() {
data.real = 0.0;
data.imag = 0.0;
}
void ComplexNumber::operator=(ComplexNumber &cplx) {
std::cout<<"assignment operator";
data.real = cplx.data.real;
data.imag = cplx.data.imag;
}
ComplexNumber::ComplexNumber(float real, float imag) {
data.real = real;
data.imag = imag;
}
ComplexNumber ComplexNumber::operator+(ComplexNumber &rhs)
{
ComplexNumber temp(data.real + rhs.data.real, data.imag+rhs.data.imag);
return temp;
}
}
using namespace ComplexNumberNamespace;
int main()
{
ComplexNumber c1(1, 2);
ComplexNumber c2(4, 3);
ComplexNumber sum = c1 + c2;
std::cout<<sum.to_string();
}
编译器输出
====================[ Build | all | Debug ]=====================================
"C:\Program Files\JetBrains\CLion 2020.3.2\bin\cmake\win\bin\cmake.exe" --build C:\Users\pc\source\repos\Doxygen\input_cpp_files\cmake-build-debug --target all -- -j 3
Scanning dependencies of target input_cpp_files
[ 50%] Building CXX object CMakeFiles/input_cpp_files.dir/MyCppFile.cpp.obj
C:\Users\pc\source\repos\Doxygen\input_cpp_files\MyCppFile.cpp: In function 'int main()':
C:\Users\pc\source\repos\Doxygen\input_cpp_files\MyCppFile.cpp:79:28: error: cannot bind non-const lvalue reference of type 'ComplexNumberNamespace::ComplexNumber&' to an rvalue of type 'ComplexNumberNamespace::ComplexNumber'
ComplexNumber sum = c1 + c2;
~~~^~~~
C:\Users\pc\source\repos\Doxygen\input_cpp_files\MyCppFile.cpp:40:5: note: initializing argument 1 of 'ComplexNumberNamespace::ComplexNumber::ComplexNumber(ComplexNumberNamespace::ComplexNumber&)'
ComplexNumber::ComplexNumber(ComplexNumber & rhs) {
^~~~~~~~~~~~~
mingw32-make.exe[2]: *** [CMakeFiles\input_cpp_files.dir\build.make:83: CMakeFiles/input_cpp_files.dir/MyCppFile.cpp.obj] Error 1
mingw32-make.exe[1]: *** [CMakeFiles\Makefile2:95: CMakeFiles/input_cpp_files.dir/all] Error 2
mingw32-make.exe: *** [Makefile:103: all] Error 2
为什么我的源代码会产生这个错误?
我做错了什么?
我该如何解决这个问题?
您的构造函数和运算符重载以 ComplexNumber&
作为参数需要取而代之的是 const ComplexNumber&
。
这一行 ComplexNumber sum = c1 + c2
实际上调用了您的 ComplexNumber 复制构造函数并给它 c1 + c2
表达式结果,这是一个临时的 ComplexNumber。由于无法在 C++ 中对临时 object 进行 non-const 引用,因此会出现此错误。
理想情况下,您的 ComplexNumber class 应该如下所示:
struct ComplexNumber {
// ...
// Copy
ComplexNumber(const ComplexNumber& other) { *this = other; }
ComplexNumber& operator=(const ComplexNumber& other) {
if (this != &other) { /* copy your attributes from other to this */ }
return *this;
}
// Move (optional - and not really useful in your case)
ComplexNumber(ComplexNumber&& other);
ComplexNumber& operator=(ComplexNumber&& other);
// Unlike operator= we return a temporary value,
// so it's a ComplexNumber indeed (no &)
// We'll modify neither 'this' nor 'rhs', so mark them const
ComplexNumber operator+(const ComplexNumber& rhs) const;
~ComplexNumber();
};
更多详情:https://en.cppreference.com/w/cpp/language/rule_of_three
一些提示:
- 不要把
using namespace std
放在 header 中(我猜是 header)
typedef struct _Data { ... } Data;
是旧的 C 表示法。您可以简单地使用 struct Type { ... } myObj;
#include <iostream>
#include <string>
using namespace std;
namespace ComplexNumberNamespace
{
typedef struct _Data
{
double real;
double imag;
}Data;
class ComplexNumber
{
private:
Data data{};
public:
ComplexNumber();
ComplexNumber(float real, float imag);
ComplexNumber(ComplexNumber&);
string to_string();
void operator = (ComplexNumber&);
ComplexNumber operator + (ComplexNumber& rhs);
};
string ComplexNumber::to_string() {
std::string str;
str = std::to_string(data.real);
str.append(" + i ");
str.append(std::to_string(data.imag));
return str;
}
ComplexNumber::ComplexNumber(ComplexNumber & rhs) {
std::cout<<"copy constructor";
data.real = rhs.data.real;
data.imag = rhs.data.imag;
}
ComplexNumber::ComplexNumber() {
data.real = 0.0;
data.imag = 0.0;
}
void ComplexNumber::operator=(ComplexNumber &cplx) {
std::cout<<"assignment operator";
data.real = cplx.data.real;
data.imag = cplx.data.imag;
}
ComplexNumber::ComplexNumber(float real, float imag) {
data.real = real;
data.imag = imag;
}
ComplexNumber ComplexNumber::operator+(ComplexNumber &rhs)
{
ComplexNumber temp(data.real + rhs.data.real, data.imag+rhs.data.imag);
return temp;
}
}
using namespace ComplexNumberNamespace;
int main()
{
ComplexNumber c1(1, 2);
ComplexNumber c2(4, 3);
ComplexNumber sum = c1 + c2;
std::cout<<sum.to_string();
}
编译器输出
====================[ Build | all | Debug ]=====================================
"C:\Program Files\JetBrains\CLion 2020.3.2\bin\cmake\win\bin\cmake.exe" --build C:\Users\pc\source\repos\Doxygen\input_cpp_files\cmake-build-debug --target all -- -j 3
Scanning dependencies of target input_cpp_files
[ 50%] Building CXX object CMakeFiles/input_cpp_files.dir/MyCppFile.cpp.obj
C:\Users\pc\source\repos\Doxygen\input_cpp_files\MyCppFile.cpp: In function 'int main()':
C:\Users\pc\source\repos\Doxygen\input_cpp_files\MyCppFile.cpp:79:28: error: cannot bind non-const lvalue reference of type 'ComplexNumberNamespace::ComplexNumber&' to an rvalue of type 'ComplexNumberNamespace::ComplexNumber'
ComplexNumber sum = c1 + c2;
~~~^~~~
C:\Users\pc\source\repos\Doxygen\input_cpp_files\MyCppFile.cpp:40:5: note: initializing argument 1 of 'ComplexNumberNamespace::ComplexNumber::ComplexNumber(ComplexNumberNamespace::ComplexNumber&)'
ComplexNumber::ComplexNumber(ComplexNumber & rhs) {
^~~~~~~~~~~~~
mingw32-make.exe[2]: *** [CMakeFiles\input_cpp_files.dir\build.make:83: CMakeFiles/input_cpp_files.dir/MyCppFile.cpp.obj] Error 1
mingw32-make.exe[1]: *** [CMakeFiles\Makefile2:95: CMakeFiles/input_cpp_files.dir/all] Error 2
mingw32-make.exe: *** [Makefile:103: all] Error 2
为什么我的源代码会产生这个错误?
我做错了什么?
我该如何解决这个问题?
您的构造函数和运算符重载以 ComplexNumber&
作为参数需要取而代之的是 const ComplexNumber&
。
这一行 ComplexNumber sum = c1 + c2
实际上调用了您的 ComplexNumber 复制构造函数并给它 c1 + c2
表达式结果,这是一个临时的 ComplexNumber。由于无法在 C++ 中对临时 object 进行 non-const 引用,因此会出现此错误。
理想情况下,您的 ComplexNumber class 应该如下所示:
struct ComplexNumber {
// ...
// Copy
ComplexNumber(const ComplexNumber& other) { *this = other; }
ComplexNumber& operator=(const ComplexNumber& other) {
if (this != &other) { /* copy your attributes from other to this */ }
return *this;
}
// Move (optional - and not really useful in your case)
ComplexNumber(ComplexNumber&& other);
ComplexNumber& operator=(ComplexNumber&& other);
// Unlike operator= we return a temporary value,
// so it's a ComplexNumber indeed (no &)
// We'll modify neither 'this' nor 'rhs', so mark them const
ComplexNumber operator+(const ComplexNumber& rhs) const;
~ComplexNumber();
};
更多详情:https://en.cppreference.com/w/cpp/language/rule_of_three
一些提示:
- 不要把
using namespace std
放在 header 中(我猜是 header) typedef struct _Data { ... } Data;
是旧的 C 表示法。您可以简单地使用struct Type { ... } myObj;