C++:左值和右值注意情况

/ C++ / 没有评论 / 1866浏览
#include <iostream>

class Foo {
public:
	Foo(int num = 0) : num_(num) 
	{
		std::cout << "default" << std::endl;
	}
	Foo(const Foo& rhs) : num_(rhs.num_) 
	{
		std::cout << "ctor" << std::endl;
	}
	Foo(Foo&& rhs) : num_(rhs.num_) 
	{
		rhs.num_ = 0;
		std::cout << "mtor" << std::endl;
	}
private:
	int num_;
};


template<typename T>
void pass_by_const_ref(const T& arg) 
{
	std::cout << &arg << std::endl;
}

template<typename T>
void pass_by_value(T arg) 
{
	std::cout << &arg << std::endl;
}

//type2:
//template<typename T>
//void pass_by_lv_ref(T& arg)
//{
//	//std::cout << arg << std::endl;
//	arg = "111";
//	std::cout << arg << std::endl;
//}

//type3:解决办法,如果是推导成const的 无法匹配
template<typename T, typename = std::enable_if_t< !std::is_const<T>::value>>
void pass_by_lv_ref(T& arg)
{
	std::cout << arg << std::endl;
}

//type4
//template<typename T>
//void pass_by_perfect_ref(T&& arg) 
//{
//	std::cout << typeid(std::forward<T&&>(arg)).name() << std::endl;
//}

template<typename T>
void pass_by_perfect_ref(T&& arg)
{
	Foo foo(std::forward<T&&>(arg));
}

template<typename T>
void pass_by_move_ref(T&& arg) 
{
	Foo foo(std::move(arg));
}

int main()
{
	//Foo foo{ 10 };
	//pass_by_const_ref(foo);
	//pass_by_const_ref(std::move(foo));
	//pass_by_const_ref(Foo{ 100 });  // 调用构造函数

	//type1:类型退化 :error
	/*const std::string str_const{ "hello Cpp" };
	std::string&& rv = std::move(str_const);*/


	//type2:传递右值会出错
	/*pass_by_lv_ref((std::string{ "temp value" });*/

	//type3:T 被推导成const 内部不能修改值  error
	/*const std::string str_const{ "hello Cpp" };
	pass_by_lv_ref(str_const);*/
	
	//type4:
	/*const std::string str_const{ "hello Cpp" };
	pass_by_perfect_ref(str_const);*/

	Foo foo{ 10 };

	pass_by_perfect_ref(foo);//ctor
	//pass_by_move_ref(foo);//mtor
	pass_by_perfect_ref(std::move(foo));//同上,mtor
	return 0;
}