C++中函数模板(function template) 的 推进(forward) 问题

函数模板在调用函数的时候, 由于实参(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,以便于您获取更多的相关知识。

时间: 2025-01-21 19:37:48

C++中函数模板(function template) 的 推进(forward) 问题的相关文章

C++中函数模板(function template) 详解

C++的模板(template)是泛型编程(generic programming)的基础; 面向对象编程 是 运行(run time)时 知道类型(type); 泛型编程 是编译(compilation) 知道类型; 函数模板(function template)包含模板参数列表(template parameter list); 每个参数类型之前必须包含关键字typename或class, 尽量使用typename, 表达意思更加明确; 非类型模板参数(Nontype Template Pa

C++中函数模板(function template) 的 重载(overload) 详解

函数模板(function template)重载, 即实例化特定的模板, 确定T的类型, 选择匹配度最高的一个; 需要注意传递的具体类型, 如传递的是"&s", 则表示"string* t = &s", 即实际匹配的类型为"string* t"; 当非函数模板和函数模板匹配度相同时, 优先选择非函数模板; 调用模板时, 一定要注意顺序, 或者提前声明, 以保证可以找到函数模板, 进行实例化; 具体参见代码注释, 代码如下: /*

C++中函数模板(function template)返回值

函数模板的返回值也可以定义为模板参数(template parameter), 但是由于无法推导(deduce), 需要显式(explicit)指定; 由于显式指定的顺序是从左至右, 返回值参数尽量放在左面,其余函数参数可以通过传入实参(argument)进行推导; 也可以提供由其他参数推导出的返回值类型, 需要使用拖尾返回类型(trailing return type); 使用decltype()函数推导, 即"编译时定义的类型", 注意使用拖尾返回类型时, 前置需要"au

C++中函数模板定制(function template specialization) 详解

函数模板定制可以解决特定的模板参数, 需要特定的函数方法去实现; 注意函数模板定制是实例化模板, 而不是模板的重载; 有非模板函数(nontemplate function)存在时, 当匹配度相同时, 优先使用非模板函数; 如比较(compare)函数, 比较字符串(char*)类型, 不能通过判断地址去比较, 应该使用strcmp()函数, 需要定制函数模板; 函数模板定制需要使用 "template<>", 空的尖括号表明 提供的模板实参支持原版本的所有模板形参; 代码

c++ 函数模板重载-关于c++中函数模板的重载问题

问题描述 关于c++中函数模板的重载问题 直接上代码(简单),enter code here template< class T > void test(T x){ cout<<x<<endl; } void test(int); int main(){ int x = 1; test(x); } 上述程序使用非模板函数对函数模板test进行重载:按照书中的说法-这个非模板函数可以只声明原型,然后借用模板中定义的函数体. 但是链接的时候找不到那个非模板函数的定义(使用的

C++中函数模板的用法详细解析_C 语言

定义 我们知道函数的重载可以实现一个函数名多用,将功能相同或者类似函数用同一个名来定义.这样可以简化函数的调用形式,但是程序中,仍然需要分别定义每一个函数. C++提供的函数模板可以更加简化这个过程. 所谓函数模板实际上是建立一个通用函数,其涵涵素类型额形参类型不具体指定,用一个虚拟的类型来代表,这个通用函数就称为函数模板. 凡是函数体相同的函数都可以用这个模板来代替,不必定义多个函数,只需要在模板中定义一次即可.在调用函数时,系统会根据实参的类型来取代模板中的虚拟类型,从而实现了不同函数的功能

函数模板

函数模板 函数模板是那些被参数化的函数,它们代表的是一个函数家族. 初探函数模板 函数模板提供了一种函数行为,该函数行为可以用多种不同的类型进行调用:也就是说,函数模板代表一个函数家族.它的表示(即外形)看起来和普通的函数很相似,唯一的区别是函数元素是未确定的:这些元素将在使用时被参数化.   定义模板 下面是一个返回两个值中最大者的函数模板: template <typename T> inline T const& max(T const &a,T const &b

object- js中先有Function还是先有Object?

问题描述 js中先有Function还是先有Object? 我们知道js中函数是Function类型的实例,而Object是一个构造函数,故也是Function类型的实例.又因为js中所有对象都是继承Object类型,Function是一个构造函数,当然也就是个对象,所以也继承Object.那这样,就有个问题,Function的产生需要Object,而Object产生又需要Function,那到底是先有哪个,js中具体是怎么实现的?有大神知道吗?这个问题貌似有点像,鸡和蛋的问题. 解决方案 从构

C++中成员函数(member function)模板(template) 详解

成员模板(member template) 既可以在普通类(ordinary class), 也可以在类模板(class template); 在普通类中, 在使用成员函数时, 不用提供模板参数, 函数可以根据使用的参数, 自动推导(deduce)模板实参(template argument)对应模板形参(template parameter); 在类模板中, 成员函数的模板参数(template parameter)可以和类的模板参数不同, 但在定义(definition)中, 必须添加两个模