C++ - 函数模板(function template) 的 推进(forward) 问题 及 解决

函数模板(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


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值