美文网首页
函数传参、模板传参、右值引用

函数传参、模板传参、右值引用

作者: Myth52125 | 来源:发表于2017-11-07 19:50 被阅读0次

    函数传参

    普通函数

    非常量引用

    在普通函数中,当形参是一个类型的引用时:

    void f1(int&);
    

    那么,函数f1可以接受下列形式的实参:

    • 一个变量,非const
      有名字的变量。
    • 返回int &类型的表达式或者是函数。
      不能是int

    不接受常量,或者是匿名变量,比如我们直接传一个1,不能接受const int类型的实参。

    常量引用

    当函数的形参是一个常量引用时:

    void f2(const int &);
    

    那么函数f2可以接受下列形式的实参:

    • 一个变量
      可以使const,也可是不是
    • 常量类型的int
    • 匿名变量
      直接是数值
    • 一个返回int类型的表达式或函数
      或是const都行。

    可见,常量的形参限制小,但是因为不能改变传入参数的值。

    模板函数

    值类型

    当函数是一个模板的时候:

    template <typename T>
    void f3(T t);
    

    那么,函数f3可以接受上面两种普通函数的形式。
    因为T可以被推断为const int,和int
    只是值类型的

    引用类型

    因此如果,想要声明为引用需要:

    template <typename T>
    void f4(T&);
    

    这样就和普通函数的第一种形式相同 了。
    同时参数也可以是const T&

    右值引用

    上面普通函数的都是左值类型的参数
    下面是右值引用

    void f(string &&);
    

    普通函数的右值引用可以接受下列形式的实参:

    • 常量表达式
      一个数字,字符串等.1,haha.
    • 匿名变量
      string("123")
    • 返回string的函数或表达式
      相当于一个匿名变量
    • move()语义

    但是不能接受变量,也就是不能接受左值

    模板参数的右值引用形参

    template <typename T>
    void f5(T&&);
    

    当函数是一个模板函数的时候,当他的形参是右值引用的时候有如下的不同:

    • 传入左值,传入值的类型被推断为类型的引用
      比如,传入string类型,那么T被推断为string&

    同时,引用折叠:怎么说,意思就是左值引用的引用就等于引用,也是是,所有的双数引用可以折叠为右值引用。
    而所有单数的引用可以折叠为左值引用

    T&& && &&=T&&
    T&& && && & =T&
    

    因此,综上棉量两点:
    T = string &&是,传入的参数类型为string& &&,因此被折叠为string &
    这就是模板函数的右值引用形参可以接受一个左值的原因。

    相关文章

      网友评论

          本文标题:函数传参、模板传参、右值引用

          本文链接:https://www.haomeiwen.com/subject/onzjmxtx.html