【C++】万能引用、完美转发

这篇具有很好参考价值的文章主要介绍了【C++】万能引用、完美转发。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

万能引用

万能引用的格式如下:

template<typename T>
void PerfectForward(T&& t)
{
	Fun(t);
}

虽然写的是&&和右值引用类似,但是它可以接收左值引用和右值引用

当传过来的是左值,那么T&&会折叠为T&

引用折叠有以下几种情况:

实参 形参 结果
&(左值) &(左值) &(左值)
&(左值) &&(右值) &(左值)
&&(右值) &&(右值) &&(右值)
&&(右值) &(左值) &(左值)

举个栗子😉

void Fun(int& x) { cout << "左值引用" << endl; }
void Fun(const int& x) { cout << "const 左值引用" << endl; }

void Fun(int&& x) { cout << "右值引用" << endl; }
void Fun(const int&& x) { cout << "const 右值引用" << endl; }



template<typename T>
void PerfectForward(T&& t)
{
	Fun(t);
}

int main()
{
	PerfectForward(10);           // 右值

	int a;
	PerfectForward(a);            // 左值
	PerfectForward(std::move(a)); // 右值

	const int b = 8;
	PerfectForward(b);		      // const 左值
	PerfectForward(std::move(b)); // const 右值

	cout << "----------------------------------" << endl;

	return 0;
}

这里输出为什么都是左值引用呢?

chatgpt的回答:

这是因为在 C++ 中,当一个命名的变量被作为参数传递给函数时,它会被视为左值,即使该变量是通过 std::move 显式转换为右值引用的。

我的理解:

因为无论是什么类型作为函数参数接收,就有了载体,就会存在一片空间去存储值了,因此原来的右值有了空间只会就有了地址,就会被认为是左值。

这种情况也被称为不完美转发。

完美转发

经过引用折叠之后,传之前的数据的引用类型和传入之后的引用类型可能发生变化,为了保证类型不会发生变化,完美转发就产生了。

std::forward<>();

对于之前的代码,加上万能转发就能够正确输出类型了。

void Fun(int& x) { cout << "左值引用" << endl; }
void Fun(const int& x) { cout << "const 左值引用" << endl; }

void Fun(int&& x) { cout << "右值引用" << endl; }
void Fun(const int&& x) { cout << "const 右值引用" << endl; }



template<typename T>
void PerfectForward(T&& t)
{
	Fun(std::forward<T>(t));
}

int main()
{
	PerfectForward(10);           // 右值

	int a;
	PerfectForward(a);            // 左值
	PerfectForward(std::move(a)); // 右值

	const int b = 8;
	PerfectForward(b);		      // const 左值
	PerfectForward(std::move(b)); // const 右值

	cout << "----------------------------------" << endl;

	return 0;
}

注意:只要使用了完美转发,每一步调用涉及到参数的都必须加上万能转发,不然就会失败。文章来源地址https://www.toymoban.com/news/detail-627257.html

到了这里,关于【C++】万能引用、完美转发的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • c++右值引用、移动语义、完美转发

    左值:一般指的是在内存中有对应的存储单元的值,最常见的就是程序中创建的变量 右值:和左值相反,一般指的是没有对应存储单元的值(寄存器中的立即数,中间结果等),例如一个常量,或者表达式计算的临时变量 左值引用:C++中采用 对变量进行引用,这种常规的引

    2024年02月05日
    浏览(53)
  • 【C++11】 initializer_list | 右值引用 | 移动构造 | 完美转发

    { } 初始化 C++11 扩大了括号括起的列表(初始化列表)的使用范围,使其可用于所有的内置类型和用户自定义类型, 使用初始化列表,可添加等号(=),也可不添加 将1赋值给x1,x2处省略了赋值符号,将5赋值给x2 同样也可以将new开辟4个int的空间初始化为0 创建对象时,可以使用列

    2024年02月08日
    浏览(70)
  • 【重学C++】04 | 说透C++右值引用、移动语义、完美转发(上)

    【重学C++】04 | 说透C++右值引用、移动语义、完美转发(上) 大家好,我是只讲技术干货的会玩code,今天是【重学C++】的第四讲,在前面《03 | 手撸C++智能指针实战教程》中,我们或多或少接触了右值引用和移动的一些用法。 右值引用是 C++11 标准中一个很重要的特性。第一

    2024年02月06日
    浏览(44)
  • 【重学C++】05 | 说透右值引用、移动语义、完美转发(下)

    【重学C++】05 | 说透右值引用、移动语义、完美转发(下) 大家好,我是只讲技术干货的会玩code,今天是【重学C++】的第五讲,在第四讲《【重学C++】04 | 说透右值引用、移动语义、完美转发(上)》中,我们解释了右值和右值引用的相关概念,并介绍了C++的移动语义以及如

    2024年02月06日
    浏览(39)
  • C++右值引用(左值表达式、右值表达式)(移动语义、完美转发(右值引用+std::forward))(有问题悬而未决)

    在 C++ 中,表达式可以分为左值表达式和右值表达式。左值表达式指的是可以出现在赋值语句左边的表达式,例如变量、数组元素、结构体成员等;右值表达式指的是不能出现在赋值语句左边的表达式,例如常量、临时对象、函数返回值等。 右值是指将要被销毁的临时对象或

    2024年02月04日
    浏览(42)
  • C++ 学习系列 1 -- 左值、右值与万能引用

    简单的说,左值可以放在等号的左边,右值可以放在等号的右边。 左值可以取地址,右值不能取地址。 1.1 左值举例: 变量、函数或数据成员 返回左值引用的表达式 如 ++x、x = 1、cout \\\' \\\'  int x = 0 1.2 右值举例: 返回非引用类型的表达式 如 x++、x + 1 除字符串字面量之外的字面

    2024年02月14日
    浏览(41)
  • C++——移动构造和完美转发

    右值引用是C++11的概念,与之对应的是左值引用。 当一个对象被用作右值的时候,用的是对象的值(内容);当对象被用作左值的时候,用的是对象的身份(在内存当中的位置)。 以上的概念是摘录自《C++ primer》。 但是这样的概念并不足以理解。 用一句简单的话描述左值和右值

    2024年02月12日
    浏览(32)
  • 任务队列C++实现-(完美转发)

    任务队列中可以 依次添加任务 ; 任务执行函数需要 接受外部传输的参数 ; 主动 调用Start开始执行任务 ; 任务队列,将需要执行的任务存储在队列中,存储的这个动作类似于 生产者 ; 当任务队列不为空时,会从队列中取出一个任务执行,当任务执行结束后再从队列取下

    2024年02月07日
    浏览(40)
  • 现代C++技术研究(8)---完美转发

    我们知道,常量左值引用既可以绑定左值,又可以绑定右值,这是C++98就存在的特性。对于如下模板函数,使用了常量左值引用,并在函数中调用了std::vector的emplace_back函数: 运行的效率不怎么样,因为函数入参是常量左值引用,在调用emplace_back函数的内部发生了拷贝动作,

    2024年02月07日
    浏览(35)
  • C++之std::forward(完美转发)

    相关系列文章 C++之std::is_object C++之std::decay C++模板函数重载规则细说 C++之std::declval C++之std::move(移动语义) C++之std::forward(完美转发) C++之std::enable_if C++之std::is_pod(平凡的数据) 目录 1.简介 2.完美转发原理 3.完美转发失败的情形 4.实例讲解         std::forward是C++11引入的函数模板

    2024年04月12日
    浏览(28)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包