函数模板在调用函数的时候, 由于实参(argument)转换形参(parameter)的时候, 会发生改变, 导致无法保留原实参的信息, 即推进(forward)问题;
主要包括: 引用和右值;引用, 即因为模板参数非引用, 导致复制操作, 无法提供引用类型;右值, 即因为模板参数只能转换为左值, 无法提供右值;
解决方法:
引用: 使用右值参数(T&& t), 可以保证传递引用不发生改变;
右值:使用右值参数, 再使用forward()函数(#include<utility>), 可以把实参转换为初始类型, 左值或右值;
更多精彩内容:http://www.bianceng.cnhttp://www.bianceng.cn/Programming/cplus/
具体参见代码注释, 及输出.
代码如下:
/* * 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
作者:csdn博客 Spike_King
以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索函数
, include
, 参数
, 模板函数
, 模板
, 函数模板
, 形参
, forward
, 右值
, 右值引用
左值c++std::move右值
arttemplate模板引擎、js template 模板引擎、stringtemplate 模板、template模板、template模板 语法 js,以便于您获取更多的相关知识。