您的位置:首页 > 编程语言 > C语言/C++

C++11 auto和decltype推导规则

2015-09-05 10:54 573 查看
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());//在vs2015中,ContainerT()会被推导为vector<int>类型,const被摒弃,所以出错。
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: