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

你可能感兴趣的:(auto,decltype,推导规则)