引用折叠(Reference collapsing)是C++11中引入的一种规则,用于处理函数模板参数的类型和值完全匹配的情况。当一个非const左值引用和一个右值引用绑定到同一块内存时,引用折叠会发生。
引用折叠的规则如下:
- 如果两个引用类型都是左值引用,那么它们会折叠为左值引用。
- 如果其中一个引用类型是左值引用,另一个是右值引用,那么它们会折叠为左值引用。
- 如果两个引用类型都是右值引用,那么它们会折叠为右值引用。
在函数模板参数中,T&&称作万能引用,可以转发const 左值引用,左值引用和右值引用。
#include <iostream>
using namespace std;
#include <type_traits>
template<typename T>
void test(T&& a){
if(std::is_lvalue_reference_v<T>)
cout << "左值引用" << endl;
else if(std::is_rvalue_reference_v<T>)
cout << "右值引用" << endl;
else
cout << "不是引用" << endl;
if(std::is_const_v<std::remove_reference_t<T>>)
cout << "常量" << endl;
cout << "-------------" << endl;
}
template<typename T>
void test2( T a){
if(std::is_lvalue_reference_v<decltype(a)>)
cout << "左值引用" << endl;
else if(std::is_rvalue_reference_v<decltype(a)>)
cout << "右值引用" << endl;
else
cout << "不是引用" << endl;
if(std::is_const_v<remove_reference_t<decltype(a)>>)
cout << "常量" << endl;
cout << "-------------" << endl;
}
template<typename T>
void test3( T& a){
if(std::is_lvalue_reference_v<decltype(a)>)
cout << "左值引用" << endl;
else if(std::is_rvalue_reference_v<decltype(a)>)
cout << "右值引用" << endl;
else
cout << "不是引用" << endl;
if(std::is_const_v<remove_reference_t<decltype(a)>>)
cout << "常量" << endl;
cout << "-------------" << endl;
}
class A{
public:
int data = 10;
};
int main(){
A a;
const A c = {};
test(a);
test(A{});
test(c);
cout << endl;
test2(a);
test2(A{});
test2(c);
cout << endl;
test3(a);
//test3(A{}); ///
test3(c);
return 0;
}