C++ - 函数模板(function template) 的 推进(forward) 问题 及 解决
2013-11-28 16:48
405 查看
函数模板(function template) 的 推进(forward) 问题 及 解决
本文地址: http://blog.csdn.net/caroline_wendy/article/details/17008287函数模板在调用函数的时候, 由于实参(argument)转换形参(parameter)的时候, 会发生改变, 导致无法保留原实参的信息, 即推进(forward)问题;
主要包括: 引用和右值;引用, 即因为模板参数非引用, 导致复制操作, 无法提供引用类型;右值, 即因为模板参数只能转换为左值, 无法提供右值;
解决方法:
引用: 使用右值参数(T&& t), 可以保证传递引用不发生改变;
右值:使用右值参数,再使用forward()函数(#include<utility>), 可以把实参转换为初始类型, 左值或右值;
具体参见代码注释, 及输出.
代码如下:
/*
* cppprimer.cpp
*
* Created on: 2013.11.28
* Author: Caroline
*/
#include <iostream>
#include <utility>
void f (int v1, int &v2)
{
std::cout << v1 << " " << ++v2 << std::endl;
}
void g (int &&i, int &j) //i为右值
{
std::cout << i << " " << j << std::endl;
}
template <typename F, typename T1, typename T2>
void flip1 (F f, T1 t1, T2 t2)
{
f(t2, t1); //反序
}
template <typename F, typename T1, typename T2>
void flip2 (F f, T1&& t1, T2&& t2) //右值传递, 保证引用性
{
f(t2, t1); //反序
}
template <typename F, typename T1, typename T2>
void flip3 (F f, T1&& t1, T2&& t2) //右值传递, 保证引用性
{
f(std::forward<T2>(t2), std::forward<T1>(t1)); //反序
}
int main (void)
{
int i(10), j(10);
f (42, i); //i传递引用发生改变
flip1 (f, j, 42); //j传递在flip1传递时是复制, 不发生改变
std::cout << "flip 1 : i = " << i << std::endl;
std::cout << "flip 1 : j = " << j << std::endl;
flip2 (f, j, 42); //j传递在flip1传递时是复制, 不发生改变
std::cout << "flip2 : j = " << j << std::endl;
g (42, i); //可以传递
//不能传递, 因为j在传递时变成左值引用, 无法赋值右值
//cannot bind 'int' lvalue to 'int&&'
//flip1 (g, j, 42);
flip3 (g, j, 42); //forward函数保证传递所有信息
return 0;
}
输出:
42 11
42 11
flip 1 : i = 11
flip 1 : j = 10
42 11
flip2 : j = 11
42 11
42 11
相关文章推荐
- 关于指针的一些事情
- C/C++数据对齐详细解析
- C++中引用的使用总结
- C++中引用(&)的用法与应用实例分析
- 解析C++ 浮点数的格式化输出
- 深入分析C++中几个最不常用的关键字
- c++中inline的用法分析
- 深入解析C++ Data Member内存布局
- 从汇编看c++中默认构造函数的使用分析
- 关于C++中的友元函数的一些总结
- C++的sstream标准库详细介绍
- 基于C++自动化编译工具的使用详解
- 浅谈C++中的string 类型占几个字节
- C/C++ 宏详细解析
- 深入分析C++中两个大数相乘结果不正确的问题
- 探讨C++中数组名与指针的用法比较分析
- 深入解析C++中的引用类型
- C++可变参数的实现方法
- C++中的常对象与常对象成员详解
- C++类成员构造函数和析构函数顺序示例详细讲解