[错误分析][Error]no match for ‘operator<<‘无匹配的左移运算符

2023-05-16

错误提示:[Error]no match for ‘operator<<’ (operand types are ‘std::basic_ostream’ and ‘plural’)

先看一下可能引发此错误的代码

#include<iostream>
using namespace std;
class plural{
	private:
		double s,x;
	public:
		plural(double s,double x):s(s),x(x){
		}
		plural(){
		}
		friend ostream& operator<<(ostream &outo,plural &a){
			outo << a.s << "+" << a.x << "i";
			return outo;
		}
		plural operator+(const plural &a){
			plural t;
			t.s = this->s + a.s;
			t.x = this->x + a.x;
			return t;
		}
};
int main(){
	plural a(1,2),b(2,3);
	cout << a + b << endl;  // 编译错误
	//[Error]no match for 'operator<<' (operand types are 'std::basic_ostream<char>' and 'plural')
	return 0;
}

根据错误提示,no match for ‘operator<<’,即没有匹配的左移运算符
显而易见,问题来自于对左移运算符,即cout<<的重载。

当把

cout << a + b << endl;

改成

cout << a << endl;

时,编译成功,0错误0警告。

为什么会这样呢?


特别关注以下的问题代码。

friend ostream& operator<<(ostream &outo,plural &a){
    outo << a.s << "+" << a.x << "i";
	return outo;
}

我们注意到,函数参数a没有使用const进行修饰。

这意味着什么呢?

意味着可以在函数中修改该参数的值?(×)

我们还注意到,参数a是引用类型。

非const的左值引用无法绑定到右值

所以问题也就水落石出了!

在语句cout << a + b << endl;中,因为a + b属于右值,而operator++函数的参数a没有使用const进行修饰,无法与作为右值a + b进行成功绑定,导致编译错误。

而在语句cout << a << endl;中,因为对象a属于左值,而operator<<的参数a为非const左值引用,可以与左值进行正常的绑定,因此编译成功。

综上所述,只要使用constoperator<<中的参数a进行修饰,问题便解决了。


如果您不太理解以上的解释,那么请继续往下看。

什么是左值和右值呢?

简单地理解,就是能放在赋值号=左侧的值称为左值,放在赋值号=右边的值称为右值

例如:

int a = 1 + 2;

在这个语句中,变量a位于等号左侧,属于左值。而1 + 2位于等号右侧,属于右值

深层理解

L-value中的L指的是Location,表示可寻址。a value (computer science)that has an address.

R-value中的R指的是Read,表示可读。in computer science, a value that does not have an address in a computer language.
(来自百度百科的解释)

左值引用和右值引用

左值引用就是对一个左值进行引用的类型。

右值引用就是对一个右值进行引用的类型。

引用与const

引用和const是约束变量的两种独立的方式。

因此根据变量引用的绑定和const修饰情况,可以将引用类型分为4种:

  1. 常左值引用
  2. 非常左值引用
  3. 常右值引用
  4. 非常右值引用

其中,非常左值引用能对所绑定的对象进行修改,但是非常左值引用只能绑定非常左值

常左值引用为万能引用,能够与以上四种种的任意一种引用类型进行绑定。

在原代码中,
对于

friend ostream& operator<<(ostream &outo,plural &a){
    outo << a.s << "+" << a.x << "i";
	return outo;
}

plural &a属于非常左值
cout << a << endl; 对象a属于左值,能够进行正常的绑定。

cout << a + b << endl;,因为a + b属于非常右值,所以无法与非常左值参数a进行成功的绑定。


本文章为本人原创。
如有疏漏欢迎指正。
欢迎在评论区和我共同探讨、学习交流呀。
原创不易,转载请说明出处。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

[错误分析][Error]no match for ‘operator<<‘无匹配的左移运算符 的相关文章

随机推荐