c++返回值不能是右值对象

右值测试

结论

  • 返回值不能为右值对象,外面接的人,会那倒一个析构的对象使用。
  • 效率最高的,返回值对象通过引用传入,在函数里面赋值。

代码


#include <iostream>
#include<iostream>
#include<cstdlib>
#include <type_traits>

using namespace std;

template <class _Ty>
_NODISCARD constexpr _Ty&& forwardtt(
	remove_reference_t<_Ty>& _Arg) noexcept { // forward an lvalue as either an lvalue or an rvalue
	return static_cast<_Ty&&>(_Arg);
}

template <class _Ty>
_NODISCARD constexpr _Ty&& forwardtt(remove_reference_t<_Ty>&& _Arg) noexcept { // forward an rvalue as an rvalue
	static_assert(!is_lvalue_reference_v<_Ty>, "bad forward call");
	return static_cast<_Ty&&>(_Arg);
}


void processValue(int& a) { cout << "lvalue" << endl; }
void processValue(int&& a) { cout << "rvalue" << endl; }
template <typename T>
void forwardValue(T&& val)
{
	processValue(forwardtt<T>(val)); //照参数本来的类型进行转发。
}
template <typename T>
void nforwardValue(T&& val)
{
	processValue(val); //照参数本来的类型进行转发。
}
template <typename T>
void moveValue(T&& val)
{
	processValue(std::move(val)); //照参数本来的类型进行转发。
}
void Testdelcl()
{
	int i = 0;
	forwardValue(i); //传入左值 
	forwardValue(0);//传入右值 
	nforwardValue(i); //传入左值 
	nforwardValue(0);//传入右值 
	moveValue(i); //传入左值 
	moveValue(0);//传入右值 
}

using namespace std;

int g_constructCount = 0;
int g_copyConstructCount = 0;
int g_copyRConstructCount = 0;
int g_destructCount = 0;
struct A
{
	A() {
		cout << "construct: " << ++g_constructCount << " ptr:" << this << endl;
	}

	A(const A& a)
	{
		cout << "copy & construct: " << ++g_copyConstructCount << " ptr:" << this << " other:" << &a << endl;
	}

	A(A&& a)
	{
		cout << "copy && construct: " << ++g_copyRConstructCount << " ptr:" << this << " other:" << &a << endl;
	}

	~A()
	{
		cout << "destruct: " << ++g_destructCount << " ptr:" << this << endl;
	}

	void Print()
	{
		cout << "111" << " ptr:" << this << endl;
	}
};

A GetA()
{
	A a = A();

	return a;
}


A&& GetAA()
{
	return A();
}

void GetA(A& a)
{
}


class RTTPrint
{
	public:
		RTTPrint(int number)
		{
			m_number = number;
			cout<< "begin:" << m_number << endl;
		}
		~RTTPrint()
		{
			cout << "end  :"<< m_number << endl;
		}
		int m_number;
};

int main()
{
	int nCounter = 0;
	{
		Testdelcl();
	}
	{
		RTTPrint rtt(nCounter++);
		A a = GetA();
		cout << "haha " << endl;
		a.Print();
	}
	{
		RTTPrint rtt(nCounter++);
		A&& a = GetA();
		cout << "haha " << endl;
		a.Print();
	}
	{
		RTTPrint rtt(nCounter++);
		A b;
		GetA(b);
	}
	{
		RTTPrint rtt(nCounter++);
		A a = GetAA();
	}
	{
		RTTPrint rtt(nCounter++);
		A&& a = GetAA();
		cout << "haha " << endl;
		a.Print();
	}

	
	return 0;
}

输出结果

lvalue
rvalue
lvalue
lvalue
rvalue
rvalue
begin:0
construct: 1 ptr:0135FCEB
copy && construct: 1 ptr:0135FE53 other:0135FCEB
destruct: 1 ptr:0135FCEB
haha
111 ptr:0135FE53
destruct: 2 ptr:0135FE53
end  :0
begin:1
construct: 2 ptr:0135FCEB
copy && construct: 2 ptr:0135FE2F other:0135FCEB
destruct: 3 ptr:0135FCEB
haha
111 ptr:0135FE2F
destruct: 4 ptr:0135FE2F
end  :1
begin:2
construct: 3 ptr:0135FE17
destruct: 5 ptr:0135FE17
end  :2
begin:3
construct: 4 ptr:0135FC33
destruct: 6 ptr:0135FC33
copy && construct: 3 ptr:0135FDFF other:0135FC33
destruct: 7 ptr:0135FDFF
end  :3
begin:4
construct: 5 ptr:0135FC33
destruct: 8 ptr:0135FC33
haha
111 ptr:0135FC33
end  :4
posted @ 2022-12-30 18:24  BackSword  阅读(18)  评论(0编辑  收藏  举报