您现在的位置是:首页 >技术交流 >现代C++技术研究(2)---模板类型推导(2)网站首页技术交流
现代C++技术研究(2)---模板类型推导(2)
简介1)当ParamType是一个通用引用时,传入左值参数,模板的类型推导ParamType结果是左值引用,且ParamType和T相同,传入右值参数,模板的类型推导ParamType结果是右值引用,但ParamType和T是不同的,T去掉引用。可以看到,推导出的类型,T和ParamType是相同的,并且后面的const被去掉了,注意,前面的const属性是不能去掉的。可以看到,对于左值,T和ParamType类型相同,对于右值,T去引用,而ParamType是右值引用。
第二种情况:ParamType是一个通用引用(Universal Reference)
这种情况,模板类型推导的结果,就不那么直观了。看如下测试用例:
#include <iostream>
#include <type_traits>
template<typename T> void f(T&& param)
{
using ParamType = T&&;
bool TIsInt = std::is_same<T, int>::value;
bool TIsConstInt = std::is_same<T, const int>::value;
bool TIsIntRef = std::is_same<T, int&>::value;
bool TIsConstIntRef = std::is_same<T, const int&>::value;
if (TIsInt) {
std::cout << "T is int, ";
} else if (TIsConstInt) {
std::cout << "T is const int, ";
} else if (TIsIntRef) {
std::cout << "T is int&, ";
} else if (TIsConstIntRef) {
std::cout << "T is const int&, ";
}
bool ParamTypeIsIntRef = std::is_same<ParamType, int&>::value;
bool ParamTypeIsConstIntRef = std::is_same<ParamType, const int&>::value;
bool ParamTypeIsIntRefRef = std::is_same<ParamType, int&&>::value;
if (ParamTypeIsIntRef) {
std::cout << "param's type is int&
";
} else if (ParamTypeIsConstIntRef) {
std::cout << "param's type is const int&
";
} else if (ParamTypeIsIntRefRef) {
std::cout << "param's type is int&&
";
}
}
int main()
{
int x = 27; // x is an int
const int cx = x; // cx is a const int
const int& rx = x; // rx is a reference to x as a const int
f(x); // x is lvalue, so T is int&, param's type is int&
f(cx); // cx is lvalue, so T is const int&, param's type is const int&
f(rx); // rx is lvalue, so T is const int&, param's type is const int&
f(27); // 27 is rvalue, so T is int, param's type is int&&
return 0;
}
可以看到,对于左值,T和ParamType类型相同,对于右值,T去引用,而ParamType是右值引用。
第三种情况:ParamType既不是指针也不是引用
1)传入的参数是引用情况:
#include <iostream>
#include <type_traits>
template<typename T> void f(T param)
{
using ParamType = T;
bool TIsInt = std::is_same<T, int>::value;
bool TIsConstInt = std::is_same<T, const int>::value;
if (TIsInt) {
std::cout << "T is int, ";
} else if (TIsConstInt) {
std::cout << "T is const int, ";
}
bool ParamTypeIsInt = std::is_same<ParamType, int>::value;
bool ParamTypeIsConstInt = std::is_same<ParamType, const int>::value;
if (ParamTypeIsInt) {
std::cout << "param's type is int
";
} else if (ParamTypeIsConstInt) {
std::cout << "param's type is const int
";
}
}
int main()
{
int x = 27; // x is an int
const int cx = x; // cx is a const int
const int& rx = x; // rx is a reference to x as a const int
f(x); // T is int, param's type is int
f(cx); // T is int, param's type is int
f(rx); // T is int, param's type is int
return 0;
}
可以看到,推导出的类型,T和ParamType是相同的,并且const和引用都被去掉了。
2)传入的参数是指针的情况:
#include <iostream>
#include <type_traits>
using PtrType = const char* const;
template<typename T> void f(T param)
{
using ParamType = T;
bool TIsCstCharPoint = std::is_same<T, const char*>::value;
bool TIsCstCharPointCst = std::is_same<T, const int* const>::value;
if (TIsCstCharPoint) {
std::cout << "T is const char*, ";
} else if (TIsCstCharPointCst) {
std::cout << "T is const char* const, ";
}
bool ParamTypeIsCstCharPoint = std::is_same<ParamType, const char*>::value;
bool ParamTypeIsCstCharPointCst = std::is_same<ParamType, const int* const>::value;
if (ParamTypeIsCstCharPoint) {
std::cout << "param's type is const char*
";
} else if (ParamTypeIsCstCharPointCst) {
std::cout << "param's type is const char* const
";
}
}
int main()
{
const char* const ptr = "Fun with pointers"; // ptr is const pointer to const object
f(ptr); // T is const char*, param's type is const char*
return 0;
}
可以看到,推导出的类型,T和ParamType是相同的,并且后面的const被去掉了,注意,前面的const属性是不能去掉的。
小结:
1)当ParamType是一个通用引用时,传入左值参数,模板的类型推导ParamType结果是左值引用,且ParamType和T相同,传入右值参数,模板的类型推导ParamType结果是右值引用,但ParamType和T是不同的,T去掉引用。
2)当模板参数是值传递时,const和volatile等修饰都会被去掉,且ParamType和T相同。
参考资料:
《Effective Mordern C++》
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。