c++11 perfect forwarding
完美转发是c++11 引入右值引用之后,在template 中的延伸. 顾名思义,完美转发是将参数不改变属性的条件下,转发给下一个函数. 因为普通函数的参数一旦具名,始终都是lvalue. 如果把rvalue转发到下一个函数上的参数中,还是rvalue.这就是完美转发的目的。
#include<iostream>
using namespace std; struct X {};
void inner(const X&) {cout << "inner(const X&)" << endl;}
void inner(X&&) {cout << "inner(X&&)" << endl;}
template<typename T>
void outer(T&& t) {inner(forward<T>(t));} int main()
{
X a;
outer(a);
outer(X());
inner(forward<X>(X()));
}
//inner(const X&)
//inner(X&&)
//inner(X&&)
那么如何支持完美转发呢?第一反应就是用通用引用;假设如此实现:
template<class T>
T&& forwarding(T&& t){
return static_cast<T&&>(param);
}
传入左值的时候是forward(x), 传入右值是forward(X()),看起来符合要求。但是这里用错了完美转发的具体场景,也就是通常我们用完美转发是什么形式呢?如果不使用完美转发,那么在template function会出现什么情况?
template <typename T>
void relay(T&& t) {
cout << "in relay" << endl;
func(t);
}
relay(temp());传入的是右值,但是转发的时候t被认为左值. 不符合完美转发语义
template<typename T>
void foo(T&& fparam)
{
std::forward<T>(fparam);
}
以上是完美转发的场景,完美转发配套通用引用,才是它的应用场景, 因为param已经具名,所以是lvalue,刚才的简单实现,显然不符合。
template <typename T>
T&& forward(typename remove_reference<T>::type& param)
{
return static_cast<T&&>(param);
}
以上实现,才是完美转发的主要实现,为什么是主要实现,因为它是最多场景的实现。我们分析一下foo(A());T被推导为A,fparam是lvalue,param是A&。因此匹配
但是如果我们翻C++ 完美转发的实现:貌似还有另外一个实现:
template <class T> T&& forward(typename remove_reference<T>::type&& t) noexcept;
这里应对什么场景呢?直接调用forward<A>(A())的场景。 注意这里typename remove_reference<T>::type&&不再是通用引用,而是右值引用。之前的左值引用,不能接右值,所以需要重定义一个函数. 以上就实现了完美转发的所有内容.完美转发的根基是引用折叠和通用引用.
template< class T > struct remove_reference {typedef T type;};
template< class T > struct remove_reference<T&> {typedef T type;};
template< class T > struct remove_reference<T&&> {typedef T type;};
c++11 perfect forwarding的更多相关文章
- 翻译「C++ Rvalue References Explained」C++右值引用详解 Part8:Perfect Forwarding(完美转发):解决方案
本文为第八部分,目录请参阅概述部分:http://www.cnblogs.com/harrywong/p/cpp-rvalue-references-explained-introduction.ht ...
- C++11--右值引用(Perfect Forwarding)
/* * 右值引用 2: Perfect Forwarding */ void foo( boVector arg ); // boVector既有移动构造又有拷贝构造 template< ty ...
- C++: Perfect Forwarding
Link: Rvalue References and Perfect Forwarding in C++0x (https://www.justsoftwaresolutions.co.uk/cpl ...
- 完美转发(perfect forwarding)、universal reference、引用折叠(collasping)
首先要分清: C++里的值只有两种值:左值.右值.—— 其本质应该是内存中存储的值/instance分两种:一种是持久的,一种是“短暂的” 也只有两种引用: 左值引用.右值引用. ——引用,就是这个内 ...
- Effective Modern C++ 42 Specific Ways to Improve Your Use of C++11 and C++14
Item 1: Understand template type deduction. Item 2: Understand auto type deduction. Item 3: Understa ...
- 【转】C++11 标准新特性: 右值引用与转移语义
VS2013出来了,对于C++来说,最大的改变莫过于对于C++11新特性的支持,在网上搜了一下C++11的介绍,发现这篇文章非常不错,分享给大家同时自己作为存档. 原文地址:http://www.ib ...
- c++11 中的 move 与 forward
[update: 关于左值右值的另一点总结,请参看这篇] 一. move 关于 lvaue 和 rvalue,在 c++11 以前存在一个有趣的现象:T& 指向 lvalue (左传引用), ...
- [转载] C++11新特性
C++11标准发布已有一段时间了, 维基百科上有对C++11新标准的变化和C++11新特性介绍的文章. 我是一名C++程序员,非常想了解一下C++11. 英文版的维基百科看起来非常费劲,而中文版维基百 ...
- C++ 11和C++98相比有哪些新特性
此文是如下博文的翻译: https://herbsutter.com/elements-of-modern-c-style/ C++11标准提供了许多有用的新特性.这篇文章特别针对使C++11和C++ ...
随机推荐
- Python使用struct处理二进制(pack和unpack用法)
转载自:http://www.cnblogs.com/gala/archive/2011/09/22/2184801.html 这篇文章写的很好,所以无耻的转了.. 有的时候需要用python处理二进 ...
- Java 代理机制
Table of Contents 1 引言 2 常见的代理 3 代理模式UML图 4 代理模式实例 5 java动态代理 5.1 java动态代理UML图 6 代理模式与装饰者模式的区别 6.1 装 ...
- 关于fastjson的一些知识
今天被问到了一些有关fastjson的知识,问了fastjson内部的实现机制,笔者只是用过fastjson这个包,还真没了解过它的机制等. 下去后搜索了一些有关fastjson的知识,希望能对自己和 ...
- Windows服务器常用的性能计数器
Windows常用性能计数器总结 基础监控: 1.SQL Server Buffer: Buffer Cache Hit Ratio 这是一个很重要查看内存是否不足的参数.SQL Server Buf ...
- [C++] How to prevent memory leaks
How to prevent memory leaks ? overload new/delete
- vector的capacity增长方式
vector的capacity()调用返回vector中最大能够存储的元素个数,也即在下一次需要扩充容量之前能容纳的元素个数.reserve会使容器在必要的时候增长,以便容纳制指定数目的元素. #in ...
- functions函数插件的定义和使用
创建Smarty插件:在插件目录(plugins)里新建文件 类型.插件名.php文件,然后插件方法名字书写规范: smarty_类型_插件名([...]){}在模板(tpl文件)中调用插件时格式{插 ...
- STL中 set 和 multiset
1. 所在头文件: <set>, 命名空间: std ; 声明如下: namespace std{ template <class T, class Compare = less&l ...
- (2)WePHP 控制器与使用模板
<?php class C_index extends Action { public function __initialize() { echo"自动执行"; } pub ...
- 在 CentOS 上部署 Nginx 环境
这里的案例主要通过虚拟机( vmware workstation (14) )的方式安装 Center OS 到本地环境 资源下载: vmware workstation / CentOS 本次 ...