#include <iostream> #include <utility> #include <string> #include <typeinfo> using std::string; template <typename T> void showMe(T str){ std::cout << typeid(T).name() << " str!!!" << std::endl; } template <> void showMe<const string>(const string str){ std::cout << "const string str" << std::endl; } template <> void showMe<string&&>(string&& str){ std::cout << "string&& str" << std::endl; } int main() { const string myStr; string myStr1; showMe(myStr); showMe(myStr1); showMe( std::move(string("haha")) ); return 0; } 程序输出结果为: 为什么没有调用使用右值形参特化的版本呢? |
|
10分 |
改成这样就能达到你想要的效果(大概)
#include <iostream> #include <utility> #include <string> #include <typeinfo> using std::string; template <typename T> void showMe(T&& str){ std::cout << typeid(T).name() << " str!!!" << std::endl; } template <> void showMe<const string&>(const string& str){ std::cout << "const string str" << std::endl; } template <> void showMe<string>(string&& str){ std::cout << "string&& str" << std::endl; } int main() { const string myStr; string myStr1; showMe(myStr); showMe(myStr1); showMe(std::move(string("haha"))); return 0; } 至于为什么,只能说标准就是这么规定的,不理解只能去读标准 template<class _Ty> typename remove_reference<_Ty>::type&& move(_Ty&& _Arg) |
10分 | |
根据楼上两位的帮助,加上MSDN上的一篇文章,我分析了一下:
对于右值实参,传给函数形参时,右值属性会丢失,所以此时T的类型为一普通类型。看下面这个例子。这个例子中template <typename T> void quark(T t) ,我们把模板函数的形参故意写为T而不是T&&。 #include <iostream> #include <string> using std::cout; using std::endl; using std::string; template <typename T> struct Name; template <> struct Name<string> { static const char * get() { return "string"; } }; template <> struct Name<const string> { static const char * get() { return "const string"; } }; template <> struct Name<string&> { static const char * get() { return "string&"; } }; template <> struct Name<const string&> { static const char * get() { return "const string&"; } }; template <> struct Name<string&&> { static const char * get() { return "string&&"; } }; template <> struct Name<const string&&> { static const char * get() { return "const string&&"; } }; template <typename T> void quark(T t) { cout << "t: " << t << endl; cout << "T: " << Name<T>::get() << endl; cout << "T&&: " << Name<T&&>::get() << endl; cout << endl; } string strange() { return "strange()"; } const string charm() { return "charm()"; } int main() { string up("up"); const string down("down"); quark(up); quark(down); quark(strange()); quark(charm()); } 函数的输出结果为: t: down t: strange() t: charm() 看后两项,发现无论是传入左值string还是右值string&&,推导出的T的类型均为普通string,对应的隐式实例化函数为: 对于一楼中的我的原问题,可以得出结论: (在模板世界中,T&& 称为Universal Reference. T&& is really special in a template function and is not a rvalue reference. It is named universal reference) template <typename T> void quark(T&& t) { cout << "t: " << t << endl; cout << "T: " << Name<T>::get() << endl; cout << "T&&: " << Name<T&&>::get() << endl; cout << endl; } t: up t: down t: strange() t: charm() 本帖在原问题和新例子之间来回跳跃,希望不影响阅读。 |