【足迹C++primer】59、模板左值右值的转换

来源:互联网 发布:淘宝卖家代理怎么发货 编辑:程序博客网 时间:2024/06/07 16:56
模板左值右值的转换


/*** 功能:模板左值右值的转换* 时间:2014年7月27日08:18:06* 作者:cutter_point*/#include<iostream>#include<algorithm>#include<utility>using namespace std;template<typename It>auto fcn(It beg, It end) -> typename remove_reference<decltype(*beg)>::type{    return *beg;    //这里返回的是beg的一个拷贝,因为用了remove_reference去除了引用}/**************************************Function Pointers and Argument Deduction**************************************/template<typename T>int compare(const T &, const T &){cout<<"template<typename T>int compare(const T &, const T &)"<<endl;}//分别实例化成int compare(const string &, const string &)作为func的参数void func(int(*)(const string &, const string &)){cout<<"void func(int(*)(const string &, const string &))"<<endl;}//分别实例化成int compare(const int &, const int &)作为func的参数void func(int(*)(const int &, const int &)){cout<<"void func(int(*)(const int &, const int &))"<<endl;}void fun1(){    int (*pf1)(const int &, const int &)=compare;   //吧compare实例化成int compare(const int &, const int &)    func(compare<int>);}/**************************************Template Argument Deduction and References**************************************//**Type Deduction from Lvalue Reference Function Parameters*//*见word文档*//**Type Deduction from Rvalue Reference Function Parameters*//*见word文档*//**Writing Template Functions with Rvalue Reference Parameters写一个模板函数带有右值引用参数*/template<typename T>T fcn2(T &t){    cout<<"t的值是:"<<t<<endl;    return t;}template<typename T>void f3(T &&val){    T t=val;    t=fcn2(t);    if(val == t)    {        cout<<"void f3(T &&val),val == t"<<endl;    }}/**************************************Understanding std::move**************************************//**std::move如何定义*///remove_reference去除类型中的引用template<typename T>typename remove_reference<T>::type &&move(T &&t)//右值{    //static_cast就相当于显示地类型转换,百度百科里面是这样    /*    int i;    float   f=166.71;    i=static_cast<int>(f);    结果i是166    */    return static_cast<typename remove_reference<T>::type &&>(t);   //都是右值!!}void fun2(){    string s1("hi!"), s2;    s2=std::move(string("bye!"));   //ok:从一个右值移动    cout<<"s2=std::move(string(bye!));s2:"<<s2<<endl;    s2=std::move(s1);   //执行之后s1有不定值    cout<<"s2=std::move(s1);s2:"<<s2<<"\n"        <<"s2=std::move(s1);s1:"<<s1<<endl;}/**************************************Forwarding**************************************/template<typename F, typename T1, typename T2>void flip1(F f, T1 t1, T2 t2){    f(t1, t2);}void f(int v1, int &v2) //v2是一个引用{    cout<<v1<<" "<<++v2<<endl;}void fun3(){    int i,j=1;    f(42, i);    cout<<"f(42, i);i:"<<i<<endl;    flip1(f, j, 42);    cout<<"flip1(f, j, 42);j:"<<j<<endl;}/**Defining Function Parameters That Retain Type Information*/template<typename F, typename T1, typename T2>void flip2(F f, T1 &&t1, T2 &&t2)   //两个都是右值引用!!{    f(t1, t2);  //吧t1+1输出。两个右值引用,那么t1和t2的值是变了的}void fun4(){    flip2(f, 8, 8);    cout<<"flip2(f, i, j);j:"<<endl;}/**Using std::forward to Preserve Type Information in a Call*//*这里forward返回的是一个右值引用,会改变值的大小*/template<typename F, typename T1, typename T2>void flip(F f, T1 &&t1, T2 &&t2){    f(std::forward<T1>(t1), std::forward<T2>(t2));}void fun5(){    int j=8;    flip(f, j, j);  //这里和上面有点不同了,注意这里第二个j要填左值参数,因为在f里面将第二个j的值改变了    //所以这里虽然传的是形参,但是forward把它还原成右值引用了,还是会改变大小    cout<<"flip(f, i, j);j:"<<j<<endl;}int main(){    cout<<">>------------------------------fun1-----------------------------------<<"<<endl;    fun1();    cout<<">>------------------------------fun2-----------------------------------<<"<<endl;    fun2();    cout<<">>------------------------------fun3-----------------------------------<<"<<endl;    fun3();    cout<<">>------------------------------fun4-----------------------------------<<"<<endl;    fun4();    cout<<">>------------------------------fun5-----------------------------------<<"<<endl;    fun5();    system("pause");    return 0;}


0 0
原创粉丝点击