完美转发(模板)--T&&
在C++模板编程中,完美转发(Perfect Forwarding)是一种技术,旨在保留函数参数的值类别,即在将参数传递到另一个函数时,无论参数是左值还是右值,都能够保持它的原始性质,而不会因为转发丢失性能或引入不必要的拷贝。
完美转发的关键在于通过模板的转发引用(Forwarding Reference),结合 std::forward,将参数以最合适的形式传递给目标函数。
为什么需要完美转发?
在某些情况下,我们希望编写一个通用的函数模板,这个函数模板接收一个可调用对象,并将参数传递给这个可调用对象。
为了避免不必要的拷贝(尤其是右值被拷贝的情况),我们需要一种机制来将参数的值类别保持下来,这就是完美转发的目的。
什么是转发引用?
当一个模板参数被定义为 T&& 时,它并不总是表示右值引用。在模板的上下文中,T&& 是一个特殊的类型,称为转发引用(有时也叫万能引用)。它具有这样的行为:
- 如果传入的是左值,
T&&被推导为T&(左值引用)。 - 如果传入的是右值,
T&&被推导为T&&(右值引用)。
这使得我们能够编写一个函数模板,既能接受左值参数,又能接受右值参数。
完美转发的核心:std::forward
完美转发的核心技术是通过 std::forward 来实现的。std::forward 是一个标准库函数,它的作用是在模板中根据参数的类型完美地转发参数:
- 如果参数是左值,
std::forward会保持它为左值。 - 如果参数是右值,
std::forward会将其转发为右值。
完美转发的使用示例
以下是一个使用完美转发的简单示例:
#include <iostream>
#include <utility> // for std::forward
// 一个通用的函数模板,用于接收任意的可调用对象和参数,并调用它
template <typename F, typename... Args>
void wrapper(F&& f, Args&&... args) {
// 使用std::forward来完美转发参数
std::forward<F>(f)(std::forward<Args>(args)...);
}
// 左值引用和右值引用的两个重载函数
void foo(int& x) {
std::cout << "Lvalue reference called: " << x << std::endl;
}
void foo(int&& x) {
std::cout << "Rvalue reference called: " << x << std::endl;
}
int main() {
int a = 10;
// 调用 wrapper,传递左值
wrapper(foo, a); // 输出: Lvalue reference called: 10
// 调用 wrapper,传递右值
wrapper(foo, 20); // 输出: Rvalue reference called: 20
return 0;
}
在这个例子中,wrapper 函数模板通过 std::forward 来实现完美转发:
- 当
wrapper(foo, a)被调用时,a是一个左值,因此foo(int& x)被调用。 - 当
wrapper(foo, 20)被调用时,20是一个右值,因此foo(int&& x)被调用。
通过 std::forward,我们能够在传递参数的过程中避免不必要的拷贝和移动,保持参数的原始值类别。
总结
完美转发是在模板编程中通过转发引用(T&&)和 std::forward 来保证参数的值类别(左值或右值)不变的一种技术。
它的目的是在模板函数中高效传递参数,避免不必要的拷贝或移动,进而提高程序性能。
完美转发(模板)--T&&的更多相关文章
- C++11新特性 变参模板、完美转发(简述)
变参模板 (Variadic Template) - 使得 emplace 可以接受任意参数,这样就可以适用于任意对象的构建 完美转发 - 使得接收下来的参数 能够原样的传递给对象的构造函数,这带来另 ...
- [C++中级进阶]001_C++0x里的完美转发到底是神马?
[C++中级进阶]001_C++0x里的完美转发到底是神马? 转载至:http://www.cnblogs.com/alephsoul-alephsoul/archive/2013/01/10/285 ...
- 翻译「C++ Rvalue References Explained」C++右值引用详解 Part8:Perfect Forwarding(完美转发):解决方案
本文为第八部分,目录请参阅概述部分:http://www.cnblogs.com/harrywong/p/cpp-rvalue-references-explained-introduction.ht ...
- 第16课 右值引用(3)_std::forward与完美转发
1. std::forward原型 template <typename T> T&& forward(typename std::remove_reference< ...
- (原创)C++11改进我们的程序之move和完美转发
本次要讲的是右值引用相关的几个函数:std::move, std::forward和成员的emplace_back,通过这些函数我们可以避免不必要的拷贝,提高程序性能.move是将对象的状态或者所有权 ...
- c++11 标准库函数 std::move 和 完美转发 std::forward
c++11 标准库函数 std::move 和 完美转发 std::forward #define _CRT_SECURE_NO_WARNINGS #include <iostream> ...
- 完美转发(perfect forwarding)、universal reference、引用折叠(collasping)
首先要分清: C++里的值只有两种值:左值.右值.—— 其本质应该是内存中存储的值/instance分两种:一种是持久的,一种是“短暂的” 也只有两种引用: 左值引用.右值引用. ——引用,就是这个内 ...
- [c++11]右值引用、移动语义和完美转发
c++中引入了右值引用和移动语义,可以避免无谓的复制,提高程序性能.有点难理解,于是花时间整理一下自己的理解. 左值.右值 C++中所有的值都必然属于左值.右值二者之一.左值是指表达式结束后依然存在的 ...
- [转][c++11]我理解的右值引用、移动语义和完美转发
c++中引入了右值引用和移动语义,可以避免无谓的复制,提高程序性能.有点难理解,于是花时间整理一下自己的理解. 左值.右值 C++中所有的值都必然属于左值.右值二者之一.左值是指表达式结束后依然存在的 ...
- Effective Modern C++:05右值引用、移动语义和完美转发
移动语义使得编译器得以使用成本较低的移动操作,来代替成本较高的复制操作:完美转发使得人们可以撰写接收任意实参的函数模板,并将其转发到目标函数,目标函数会接收到与转发函数所接收到的完全相同的实参.右值引 ...
随机推荐
- Beizer。。。。。
<html> <head>AS</head> <script> var cvs; var context; //context.fill();//填充 ...
- .NET 控件转图片
Windows应用开发有很多场景需要动态获取控件显示的图像,即控件转图片,用于其它界面的显示.传输图片数据流.保存为本地图片等用途. 下面分别介绍下一些实现方式以及主要使用场景 RenderTarge ...
- FP分数规划在无线通信中的应用
更多精彩内容请关注微信公众号 '优化与算法' 前言 在数学优化中,分数规划是线性分式规划的推广.分数规划中的目标函数是两个函数的比值,这两个函数通常是非线性的.要优化的比值通常描述系统的某种效率. 1 ...
- LangChain的LCEL和Runnable你搞懂了吗
LangChain的LCEL估计行业内的朋友都听过,但是LCEL里的RunnablePassthrough.RunnableParallel.RunnableBranch.RunnableLambda ...
- 前端使用 Konva 实现可视化设计器(19)- 连接线 - 直线、折线
本章响应小伙伴的反馈,除了算法自动画连接线(仍需优化完善),实现了可以手动绘制直线.折线连接线功能. 请大家动动小手,给我一个免费的 Star 吧~ 大家如果发现了 Bug,欢迎来提 Issue 哟~ ...
- EF Core性能优化技巧
代码层面的优化 1. 使用实例池 EFCore2.0 为DbContext引入新的注册方式:透明地注册了 DbContext实例池,使用这种方式可以避免始终创建新的实例,EF Core 将重置其状态并 ...
- 【DataBase】SQL优化问题
在DAO层的动态SQL: //订单新增,查询配件主数据 @SuppressWarnings("rawtypes") public PageInfoDto getPartsForPa ...
- 【C】Re02
一.命令行参数 #include <stdio.h> /** * 运行执行程序的命令携带 一些附加参数,传递给程序执行 * @param argc 命令行参数的个数 * @param ar ...
- 【Project】原生JavaWeb工程 03 单表的业务功能
年级表效果图样例: 可以看到主要分为以下这些功能: 功能一:展示年级列表 功能二:每个年级都具备修改和删除 功能三:添加一个年级 功能四:对多个年级选中删除,也可以全选删除,或者反选删除 功能五:根据 ...
- “refer to”和“refer to as”在英语中的用法有所不同
"refer to"和"refer to as"在英语中的用法有所不同,具体区别如下: Refer to "Refer to"意为" ...