#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() 本帖在原问题和新例子之间来回跳跃,希望不影响阅读。 |
|