C++ error: cannot bind non-const lvalue reference of type ‘myString&’ to an rvalue of type ‘m…

Look at the code first (if you don’t want to look at the code, you can directly look at the problem description after the code)

//header.h
#ifndef _HEADER_H
#define _HEADER_H
#define defaultSize 128
#include<iostream>
#include<string.h>
using namespace std;
class myString
{
	private:
		char *ch;
		int curLength;
		int maxSize;
	public:
		myString(int sz=defaultSize);
		myString(const char *init);
		myString(const myString& ob);
		~myString(){delete []ch;}
		void print();
		int Length()const;
		myString operator()(int pos, int len);
		myString& operator = (myString& ob);
};
myString& myString::operator = (myString& ob)
{
	if(&ob!=this)
	{
		delete[]ch;

		this->ch = new char[ob.maxSize];
		this->maxSize = ob.curLength;
		strcpy(this->ch, ob.ch);
		this->curLength = ob.curLength;
	}
	else
	{
		cerr<<"String copy error\n";
	}
	return *this;
}

myString myString::operator()(int pos, int len)
{
	myString temp;
	if(pos<0 || len<=0 || pos+len-1>=this->maxSize)
	{
		temp.curLength = 0;
		temp.ch[0] = '\0';
	}
	else
	{
		if(pos+len-1 >= this->curLength)
			len = this->curLength-pos;
		temp.curLength = len;
		for(int i=0,j=pos; i<len; ++i,++j)
			temp.ch[i] = this->ch[j];
		temp.ch[len] = '\0';
	}
	return temp;
}

int myString::Length()const
{
	return this->curLength;
}

void myString::print()
{
	cout<<this->ch<<endl;
}

myString::myString(int sz)
{
	this->maxSize = sz;
	this->ch = new char[this->maxSize+1];
	if(this->ch == NULL)
	{
		cerr<<"Allocation ERROR\n";
		exit(1);
	}
	this->curLength = 0;
	ch[0] = '\0';
}

myString::myString(const char *init)
{
	int len = strlen(init);
	this->maxSize = (len > defaultSize) ?len : defaultSize;
	this->ch = new char[this->maxSize+1];
	if(this->ch == NULL)
	{
		cerr<<"Application Memory ERROR\n";
		exit(1);
	}

	this->curLength = len;
	strcpy(this->ch, init);

}

myString::myString(const myString& ob)
{
	this->maxSize = ob.maxSize;
	this->ch = new char[this->maxSize+1];
	if(this->ch == NULL)
	{
		cerr<<"Application Memory ERROR\n";
		exit(1);
	}
	this->curLength = ob.curLength;
	strcpy(this->ch, ob.ch);

}

#endif
//main.cpp
#include"header.h"

int main()
{
	myString st(10), st1("ABCDEFG");
	myString st2(st1);
	st.print(), st1.print(), st2.print();
	st = st1(0, 4);//???
	st.print();
	return 0;
}

This is a string class. The problem is two symbol overloads, () and=

() overloading is to slice a string object and return a temporary object. Needless to say, = overloading is assignment

The problem is that it is always impossible to assign the sliced temporary object to the object before the equal sign

After searching on the Internet, I found a similar problem

https://blog.csdn.net/u011068702/article/details/64443949

That is to say, there is a temporary variable in ST1 (0,4). When the temporary variable is passed to st, because in the = overloaded function declaration, the parameter is mystring & amp;, It’s not a constant reference

This error is a semantic limitation of the C + + compiler

If a parameter is passed in as a non const reference, the C + + compiler has reason to think that the programmer will modify the value in the function, and the modified reference will play a role after the function returns. But if you pass in a temporary variable as a non const reference parameter, because of the particularity of the temporary variable, the programmer cannot operate the temporary variable, and the temporary variable may be released at any time. Therefore, generally speaking, it is meaningless to modify a temporary variable, The C + + compiler adds the semantic restriction that temporary variables cannot be used as non const references

After understanding this semantics, it’s easy to add const constant restrictor to = overload parameter

(class = overloaded function declaration, don’t forget to add const)

Add the running result of later program

Yes, that’s right

Conclusion:

Temporary variables in C + + cannot be used as reference parameters of non const

Updated on December 14, 2019

Recently, I saw a similar problem, that is, C + + 11

int i=0;
++++i;//right
i++++;//wrong

We know that the former + + is to automatically add the object and then return the object, and the latter + + will first return the current value of the record, then automatically add, and finally return an unnamed temporary object. Then I + + + is to automatically add the unnamed temporary object returned by the first latter + +, which is meaningless to C + +, so it cannot be compiled// PS. this is often said to take one corner with three corners

Similar Posts: