先看一段代码:
template<typename T>
void myfunc(T& tmprv) {
cout << "--------------------begin--------------------" << endl;
using boost::typeindex::type_id_with_cvr;
cout << "T=" type_id_with_cvr<T>().pretty_name() << endl; // 显示T类型
cout << "tmprv=" << type_id_with_cvr<decltype(tmprv)>().pretty_name() << endl;
cout << "---------------------end--------------------" << endl;
}
这些代码的主要作用是显示模板参数T的类型信息以及函数模板中参数tmprv的类型信息。
如果将myfunc()函数模板形参列表中的tmprv类型从T&修改为cost T&,如下所示:
template<typename T>
void myfunc(const T& tmprv) {
...
}
int main() {
myfunc(100);
}
结果显示T被推断为int类型,tmprv被推断为const int &类型。T的类型不仅和调用这个函数模板时传入的实参(100)有关,还和整个tmprv的类型(const T&)有关。
指针或引用类型
如果tmprv是引用类型,但不是万能引用,把刚才myfunc()函数模板形参的tmprv类型从const T &修改回T &,如下所示:
template<typename T>
void functest(T& tmprv) {
...
}
int main() {
int i = 10; // i的类型为int
const int j = i; // j的类型为const int
const int& k = i; // k的类型为const int &
myfunc(i); // result T = int, tmprv = int &
myfunc(j); // result T = int const, tmprv = int const &
myfunc(k); // result T = int const, tmprv = int const &
}
根据结果显示,可以得出以下结论:
- 若实参是引用类型,则引用部分会被忽略掉,T不会被推导为引用类型;
- 当向引用类型的形参tmprv传入const类型实参时,形参就会成为const引用,实参的const属性会成为类型模板参数T类型推导的组成部分;
如果tmprv是指针类型,修改myfunc()函数模板形参列表中的tmprv类型,如下所示:
template<typename T>
void mufunc(T* tmprv) {
...
}
int main() {
int i = 10;
const int* pi = &i;
myfunc(&i); // T = int, tmprv = int*
myfunc(pi); // T = int const, tmprv = int const *
}
根据结果显示,可以得出以下结论:
- tmprv中如果没有const,则实参中的const会被代入T类型;如果有const,则T类型中不会带const。
万能引用类型
修改myfunc()函数模板形参列表中的tmprv类型,如下所示:
template<typename T>
void myfunc(T&& tmprv) {
...
}
int main() {
int i = 10;
const int j = i;
const int& k = i;
myfunc(i); // i是左值, T = int &, tmprv = int &
myfunc(j); // j是左值,T = int const &, tmprv = int const &
myfunc(k); // k是左值,T = int const &, tmprv = int const &
myfunc(100); // 100是右值,T = int, tmprv = int&&
}
标签:tmprv,const,函数,int,myfunc,推断,类型,模板 From: https://www.cnblogs.com/love-9/p/18106118