【C/C++】【C++11】万能引用
类型区别基本概念
#include <iostream>
using namespace std;
template <typename T>
void func(const T &val){}
//T是什么类型;
//val是什么类型;
int main()
{
func(10);
//T是什么类型;int
//val是什么类型; const int &
//调用函数模板时候,参数会对T的类型产生影响;val的类型会对T的类型产生影响;
return 0;
}
universal reference/万能引用/未定义引用
范例1
#include <iostream>
using namespace std;
//普通函数 参数是右值引用
void func(int&& tmp)
{
cout << tmp << endl;
}
int main()
{
int&& tmp = 100;
func(100);
int val = 100;
//func(val); 右值引用不能绑定左值;
return 0;
}
万能引用
#include <iostream>
using namespace std;
template <typename T>
void func(T&& tmp) //&&属于tmp类型的一部分,与T无关;
{
cout << tmp << endl;
}
int main()
{
int&& tmp = 100;
func(100);
int val = 10;
func(val); //func为普通函数时候,错误 ; 改成函数模板之后,实参为左值也不报错;
//编译没报错,T推断出来的不是简单的int
//万能引用语境:
// 1. 必须是函数模板;
// 2. 必须是发生了模板类型推断并且函数模板形参的样子是T &&;
// auto的类型也存在万能引用;
//T &&就是万能引用;
return 0;
}
右值引用和万能引用的区别
- 右值引用得传递右值,否则编译器报错;
- 万能引用做函数形参时候,可以传递给它左值,也可以传递给它右值;
- T&& 是万能引用
1. void func(int &¶){}; //右值引用
2. template<typename T> void func(T&& tmp){}; //万能引用
3. template<typename T> void func(std::vector<T> &&tmp){}; //右值引用
万能引用资格的剥夺和辨认
剥夺
const修饰符会剥夺一个引用成为万能引用的资格,成为右值引用
辨认
类模板中的成员函数的参数
#include <iostream>
using namespace std;
template <typename T>
class Test
{
public:
void func(T&& x) {}; //右值引用,不是万能引用;
//因为 func是成员函数,不需要进行类型推断;
};
int main()
{
Test<int> mc;
int i = 100;
mc.func(i);
return 0;
}
类模板中的函数模板
#include <iostream>
using namespace std;
template <typename T>
class Test
{
public:
template <typename U>
void func(U&& x) //万能引用
{
cout << x << endl;
}
};
int main()
{
Test<int> mc;
int i = 100;
mc.func(i);
return 0;
}
知识的价值不在于占有,而在于使用