template<typename T>
void f(ParamType param);
template<typename T>
void f(T& param);
int x = 27;
const int cx = x;
const int& rx = x;
f(x);// T是int,param类型是int&
f(cx);// T是const int, param类型是const int&
f(rx); // T是const int, param类型是const int&
template<typename T>
void f(const T& param);
f(x); // T是int, param的类型是const int&
f(cx); // T是int, param的类型是const int&
f(rx); // T是int, param的类型是const int&
const int* px = &x;
f(&x); //T是int, param的类型是int*
f(px); //T是const int, param的类型是const int*
template<typename T>
void f(T&& param);
int x = 27;
const int cx = x;
const int& rx = x;
f(x); //x是左值,T是int&,param类型是int&
f(cx);//cx是左值,T是const int&,param类型是const int&
f(rx); //rx是左值,T是const int&,param类型是const int&
f(27);//27是右值,T是int,param类型是int&&
template<typename T>
void f(T param);
int x = 27;
const int cx = x;
const int& rx = x;
f(x); // T和param的类型都是int
f(cx);// T和param的类型都是int
f(rx); // T和param的类型都是int
template<typename T>
void f(T param);
const char* const ptr = "fun with pointers";
f(ptr);
//此时只会忽略掉指针本身的const
//但是对于指向对象的const会被保留
//即ptr的类型是const char*
const char name[] = "J.P.Briggs";
//name的类型是const char[13]
const char* ptrToName = name;
//数组蜕化成指针
template<typename T>
void f(T param);
f(name);
//按值传递给模板函数的数组
//模板参数会被推导成指针
//name的类型是const char*
template<typename T>
void f(T& param);
f(name);
//按引用传递给模板函数的数组
//类型仍然是数组,name的类型是const char[13]
//而模板参数类型是 const char(&)[13]
void someFunc(int, double);
template<typename T>
void f1(T param);
template<typename T>
void f2(T& param);
// 参数被推导为函数指针,param类型是 void (*)(int, double)
f1(someFunc);
// 参数被推导为函数引用,param类型是void (&)(int, double)
f2(someFunc);
auto x1 = 27; //类型是int, 值是27
auto x2 (27); //类型是int, 值是27
auto x3 = {27}; //类型是std::initializer_list<int>,值是{27}
auto x4 {27}; //类型是std::initializer_list<int>,值是{27}
auto x5 = {1,2,3.0}; // 错误,值类型不止有一种
auto x6 = {11,9,3}; //类型被推导为std::initializer_list<int>
template<typename T>
void f(T param);
f({11,23,9}); //错误,模板函数拒绝推导
template<typename T>
void f(std::initializer_list<T> initlist);
f({11,23,9}); //正确,参数被推导为std::initializer_list<int>
auto createInitList()
{
return {1,2,3}; //错误,不能推导返回值类型为初始化列表的值
}
std::vector<int> v;
...
auto resetV = [&v](const auto& newValue) { v = newValue; };
...
resetV({1,2,3}); //错误,不能推导模板函数为初始化列表的值
template<typename Container, typename Index>
auto authAndAccess(Container& c, Index i) -> decltype(c[i])
// 前面使用的auto和类型推导无关,它只是暗示语法使用了C++11的尾置返回类型
{
authenticateUser();
return c[i];
}
//C++14的格式
template<typename Container, typename Index>
auto authAndAccess(Container& c, Index i)
{
authenticateUser();
return c[i]; //本来应该返回对c[i]的引用
}
//C++14的做法
template<typename Container, typename Index)
decltype(auto) authAndAccess(Container& c, Index i)
{
authenticateUser();
return c[i]; //可以返回引用,因为decltype会保留原始类型
}
//C++14做法
template<typename Container, typename Index>
decltype(auto) authAndAccess(Container&& c, Index i)
{
authenticateUser();
return std::forward<Container>(c)[i];
//因为不知道需要返回的是什么值,因此需要使用完美转发
//当传入的参数是左值时,就返回引用,传入参数是右值时,就返回右值
}
//C++11
template<typename Container, typename Index>
auto authAndAccess(Container&& c, Index i) -> decltype
(std::forward<Container>(c)[i])
{
authenticateUser();
return std::forward<Container>(c)[i];
}
Widget w;
const Widget& cw = w;
auto myWidget1 = cw; //类型为Widget
decltype(auto) myWidget2 = cw; //类型为const Widget&
decltype(auto) f1()
{
int x = 0;
...
return x; //返回类型为int
}
decltype(auto) f1()
{
int x = 0;
...
return (x); //返回类型为int&
}
template<typename T>
class TD;
TD<decltype(x)> xType; //编译器会报告x的类型
TD<decltype(y)> yType;
std::cout<< typeid(x).name();
std::cout<< typeid(x).name();
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。