C++11标准以后的C++被称为现代C++,对于如下模板函数:
template void f(ParamType param);
对模板函数f的调用:
f(expr); // call f with some expression
第一种情况:ParamType是引用或者指针,但不是通用引用(Universal Reference)。
1)对于引用:
#include <iostream>
#include <type_traits>
template<typename T> void f(T& param)
{
using ParamType = T&;
bool isInt = std::is_same<T, int>::value;
bool isConstInt = std::is_same<T, const int>::value;
if (isInt) {
std::cout << "T is int, ";
} else if (isConstInt) {
std::cout << "T is const int, ";
}
bool isIntRef = std::is_same<ParamType, int&>::value;
bool isConstIntRef = std::is_same<ParamType, const int&>::value;
if (isIntRef) {
std::cout << "param's type is int&\n";
} else if (isConstIntRef) {
std::cout << "param's type is const int&\n";
}
}
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 const int, param's type is const int&
f(rx); // T is const int, param's type is const int&
return 0;
}
代码中通过std::is_same模板函数来验证T和ParamType的类型推导结果。
2)对于const引用:
#include <iostream>
#include <type_traits>
template<typename T> void f(const T& param)
{
using ParamType = const T&;
bool isInt = std::is_same<T, int>::value;
bool isConstInt = std::is_same<T, const int>::value;
if (isInt) {
std::cout << "T is int, ";
} else if (isConstInt) {
std::cout << "T is const int, ";
}
bool isIntRef = std::is_same<ParamType, int&>::value;
bool isConstIntRef = std::is_same<ParamType, const int&>::value;
if (isIntRef) {
std::cout << "param's type is int&\n";
} else if (isConstIntRef) {
std::cout << "param's type is const int&\n";
}
}
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 const int&
f(cx); // T is int, param's type is const int&
f(rx); // T is int, param's type is const int&
return 0;
}
与引用情况类似。
3)指针:
#include <iostream>
#include <type_traits>
template<typename T> void f(T* param)
{
using ParamType = T*;
bool isInt = std::is_same<T, int>::value;
bool isConstInt = std::is_same<T, const int>::value;
if (isInt) {
std::cout << "T is int, ";
} else if (isConstInt) {
std::cout << "T is const int, ";
}
bool isIntPoint = std::is_same<ParamType, int*>::value;
bool isConstIntPoint = std::is_same<ParamType, const int*>::value;
if (isIntPoint) {
std::cout << "param's type is int*\n";
} else if (isConstIntPoint) {
std::cout << "param's type is const int*\n";
}
}
int main()
{
int x = 27; // x is an int
const int *px = &x; // px is a ptr to x as a const int
f(&x); // T is int, param's type is int*
f(px); // T is const int, param's type is const int*
return 0;
}
对于指针,与引用的情况类似。
小结:对于ParamType是引用或者指针,但不是通用引用的场景,模板参数T会去掉引用或者指针。
参考资料:
《Effective Mordern C++》