模板左值右值的转换
/** * 功能:模板左值右值的转换 * 时间: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; }
【足迹C++primer】59、模板左值右值的转换
时间: 2024-10-05 23:36:46