VS2015下测试:
decltype:
class Foo {};
int &func_int_r(void) { int i = 0; return i; };
int &&func_int_rr(void) { return 0; };
int func_int(void) { return 0; };
const int &func_cint_r(void) { int i = 0; return i; };
const int &&func_cint_rr(void) { return 0; };
const int func_cint(void) { return 0; };
const Foo func_cfoo(void) { return Foo(); };
int main()
{
{
int x = 0;
decltype(func_int_r()) al = x; // al -> int &
decltype(func_int_rr()) bl = 0; // bl -> int &&
decltype(func_int()) cl = 0; // cl -> int
decltype(func_cint_r()) a2 = x; // a2 -> const int &
decltype(func_cint_rr()) b2 = 0; // b2 -> const int &&
decltype(func_cint()) c2 = 0; // c2 -> int
decltype(func_cfoo()) d2 = Foo(); // d2 -> Foo
decltype((x)) t = x; // t -> int &
decltype(x + 1) t2; // t2 -> int 表达式
decltype(++x) t3 = x; // t3 -> int & 表达式返回左值 decltype((++x)) t4 = x; // t6 -> int &
decltype((1)) t5 = x; // t4 -> int
decltype(1) t6 = x; // t5 -> int
int i = 0;
}
system("pause");
return 0;
}
- 当函数返回的是右值时,decltype会摒弃cv操作符。c2,d2
- 当标识符加上()后,decltype结果为左值引用。t,t4
- 当表达式赋值给左值时,decltype结果为左值引用。t3
-其它按简单推导即可。
应用:
template<class ContainerT>
class Foo
{
typename ContainerT::iterator it_; //类型定义可能有问题
public:
void func(ContainerT& container)
{
it_ = container.begin();
}
};
int main()
{
typedef const vector<int> container_t;
container_t arr;
Foo<container_t> foo;
foo.func(arr);
system("pause");
return 0;
}
编译时报错,因为当ContainerT是一个const时,it_应该是const_iterator;解决方法:
template<class ContainerT>
class Foo
{
private:
//decltype(ContainerT().begin()) it_;//在vs2015中,ContainerT()会被推导为vector<int>类型,const被摒弃,所以出错。
decltype(std::declval<ContainerT>().begin()) it_;//替代方法
static ContainerT gi;//第二种方法
decltype(gi.begin()) it_; //不会执行表达式,只会推导,跟auto不同
public:
void func(ContainerT& container)
{
decltype(ContainerT()) tt;
it_ =container.begin();
int i = 0;
}
};
int main()
{
using container_t= const vector<int> ;
container_t arr;
Foo<container_t> foo;
foo.func(arr);
system("pause");
return 0;
}
返回类型后置语法:
template<typename U,typename R>
auto add(U u, R r)->decltype(u + r)
{
return u + r;
}
int main()
{
cout << add(100, 100.0f) << endl;
cout<<add<int,float>(100, 100.0f) << endl;
system("pause");
return 0;
}
auto:
- 当auto后面显式添加&时,才会保留表达式cv限定符和引用。
- 当auto推导结果为指针时,保留cv操作符。
- 其它情况不保留cv限定符和引用。
int main()
{
int x = 0;
const auto* a = &x; // a -> const int *
auto b = &x; // b -> int *
auto &c = x; // c -> int &
auto d = c; // d -> int
const auto e = x; // e -> const int
auto f = e; // f -> int
const auto& g = x; // g -> const int &
auto& h = g; // h -> const int &
const auto i = g; // i -> const int
auto j = a; // j -> const int *
const int ci = i, &cr = ci;
auto d1 = &i; // d1 -> const int *
auto e1 = &ci; // e1 -> const int *
system("pause");
return 0;
}