右值测试
结论
- 返回值不能为右值对象,外面接的人,会那倒一个析构的对象使用。
- 效率最高的,返回值对象通过引用传入,在函数里面赋值。
代码
#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