C++11 auto和decltype推导规则

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;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

原文地址:https://www.cnblogs.com/ggzone/p/4786405.html