• 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;
    }
  • 相关阅读:
    8张图带你轻松温习 Java 知识.md
    关于 Java 序列化你不知道的 5 件事
    为什么 String 是不可变的?
    如何使用 Nginx 优雅地限流?
    JAVA泛型编程笔记
    java_接口的应用
    java_抽象类应用
    深入理解Java的接口和抽象类
    java_重写与重载的区别
    Java:按值传递还是按引用传递详细解说
  • 原文地址:https://www.cnblogs.com/ggzone/p/10121258.html
Copyright © 2020-2023  润新知