/*
auto : 由编译器推断类型
decltype (表达式) -> 推断出类型 , 比如: decltype(1+2) -> int;
decltype 需要注意 :表达式能明确类型才能推断出来, 如果是模板参数则无法推断,因为
模板类型参数总是在实例化后才能确定.
尾置: 在函数后使用 -> 类型; 函数返回类型需要加个 auto;
: auto f() -> double;
*/
// 尾置一般的形式:
auto func() -> double (*)[100]
{
}
//另外一种返回使用decltype , 不需要尾置,但需要明确类型.这种不叫尾置
int arr[] = {};
decltype(arr) func()
{
}
//需要注意:
auto func() //编译出错. 前面加了auto ,说明这是一个尾置, 需要加 ->Type;
{}
//把auto 与 decltype 结合
auto func() -> decltype(arr)
{}
//在模板中;
template <typename Iter>
auto func(Iter begin, Iter end) -> decltype(*begin) //告诉编译器返回类型与decltype推断的一样
{
return *begin;
}
//此时如果要复制一份元素,而不是元素怎么办呢? remove_reference
/*
remove_reference: 有1个type的类型成员
比如:
remove_reference<int&>::type => int
remove_reference<double&>::type => double
由于 decltype(*begin) 可以由编译器推断
那么我们可以把上面的声明返回类型修改为: remove_reference< decltype(*begin) >::type
这样就可以去除引用了 ;
但是这样不行 ,需要加上 typename 关键字 :
typename remove_reference< decltype(*begin) >::type ;
一定要加typename 说明这个 type 是类型 , 而不是静态成员变量.
*/
template <typename Iter>
auto func(Iter begin, Iter end) -> typename remove_reference<decltype(*begin)>::type
{
return *begin;
}