C++ 以模板类型参数的引用为参数的函数模板的实参推断 (左值引用形参和右值引用形参)

本文深入探讨了C++中左值引用、const左值引用及右值引用的概念与使用方法,并通过具体示例展示了不同类型引用的特点及其适用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

第一种 普通左值引用类型

template<typename T>
void change(T& x) {  // 函数参数是模板类型参数的一个左值引用
	x = 12;
}

 函数参数是模板类型参数的一个左值引用:

  • 只允许传递一个左值(此时T会被推断为左值的类型,而函数的实参则是这个类型的左值引用),若传右值,会报错:

int x = 12;
change(x);
cout << x << endl;   // 正确,x为int,T=int,实参为int&, x会被修改为12

change(1);  // 编译错误


/*
testch16.cpp(40): error C2664: “void change<int>(T &)”: 无法将参数 1 从“int”转换为“int &”
1>        with
1>        [
1>            T=int
1>        ]
*/

 

  • 左值可以是const类型,比如:(传参没问题,但是会编译报错,因为T会被推断为const int型)
const int x = 12;
change(x);
cout << x << endl;


/*
error C3892: “x”: 不能给常量赋值
testch16.cpp(37): note: 参见对正在编译的函数 模板 实例化“void change<const int>(T &)”的引用
1>        with
1>        [
1>            T=const int
1>        ]
*/

第二种 const 左值引用类型

则上面的三种传参皆可通过编译

template<typename T>
void change2(const T& x) {
	x = 12;
}



	int x = 1;
	const int cx = 1;
	change2(x); // T=int   实参为const int&
	cout << x << endl;
	change2(cx);// T=int   实参为const int&
	cout << x << endl;
	change2(1);// T=int   实参为const int&   右值可以传给一个const 左值引用


当然在函数内部编译器会发现试图修改底层const的行为并抛出错误

第三种 函数参数是右值引用类型

template<typename T>
void change3(T&& x) {
	x = 12;
}

直接传右值引用即可

	change3(22);   // T=int 实参是int&&
	int&& xx = 22;
	cout << xx << endl;
	change3(xx);  // T=int 实参是int&&  xx所绑定的值被改变
	cout << xx << endl;

给这个模板参数传左值,问题就出现了:——右值引用是不可以被绑定到左值上的。但这里有两个例外:

  1. 模板类型参数T的推断:若传给函数一个X类型的左值,且函数的参数是模板类型参数T的右值引用T&&时,T会被推断为X&,而不是X;
  2. 关于多引用的“折叠”:上面得出函数的实参为X& &&—— X的左值引用的右值引用——,通过“折叠”规则,会得出函数的实参为X&:
    X& &   -> X&
    X&& &  -> X&
    X& &&  -> X&
    X&& && -> X&&

    根据上面两条规则,即可对下面这样的调用推断模板类型参数T和函数实参的类型:

const int yy = 22;
change3(yy);



//yy是const int;T=const int&; 函数的实参是const int& &&,折叠为 const int & 编译器发现常量被修改,抛错误
/*
testch16.cpp(30): error C3892: “x”: 不能给常量赋值
testch16.cpp(57): note: 参见对正在编译的函数 模板 实例化“void change3<const int&>(T)”的引用
1>        with
1>        [
1>            T=const int &
1>        ]
*/

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值