• decltype关键字


    decltype关键字:
    1.计算表达式的类型
    sizeof操作符的值是一个整数,表示类型的长度(字节数)
    typeid操作符的值是一个对象,其中包含了类型的信息
    decltype操作符的值是一个类型,可用于其它对象的声明

     1 #include <iostream>
     2 #include <typeinfo>
     3 using namespace std;
     4 int main (void)
     5 {
     6    int a = 0;
     7    //int b = 1;
     8   //auto b = a;
     9    //b:int,decltype的值就是表达式的类型本身
    10    decltype (a) b = 1;
    11    cout << typeid (b).name () << endl; // i
    12   // c:int,decltype只在编译期计算表达式的类型,不在运行期计算表达式的值
    13   decltype (a++) c = 2;
    14   cout << typeid (c).name () << endl; // i
    15   cout << a << endl; // 0
    16   int const& d = a;
    17   // e:int const&,decltype会保留表达式的引用属性和CV限定
    18   decltype (d) e = d;
    19   cout << &e << ' ' << &a << endl; // 地址相同
    20   /* e带有常属性
    21   cout << ++e << endl; */
    22   //f:int,auto会丢弃表达式的引用属性和CV限定
    23   auto f = d;
    24   cout << &f << ' ' << &a << endl; // 地址不同
    25   cout << ++f << endl; // 1
    26   //g:int*,h:int**,decltype可以和指针联用
    27   decltype (a) *g= &a, **h = &g;
    28   cout << typeid (g).name () << endl; // Pi
    29   cout << typeid (h).name () << endl; // PPi
    30   // h---->g---->a
    31   //int** int* int
    32   //i:int const&,decltype可以和引用以及CV限定联用
    33   decltype (a) const& i = a;
    34   cout << &i << ' ' << &a << endl; // 地址相同
    35   /* i带有常属性
    36   cout << ++i << endl; */
    37   return 0;
    38 }

    2.对于函数表达式,decltype将返回该函数返回值的类型,对于左值表达式,decltype返回该表达式的左值引用

     1 #include <iostream>
     2 #include <typeinfo>
     3 using namespace std;
     4 int max (int x, int y)
     5 {
     6   return x < y ? y : x;
     7 }
     8 int* max (int* x, int* y)
     9 {
    10   return *x < *y ? y : x;
    11 }
    12 int const& min (int const& x, int const& y)
    13 {
    14   return x < y ? x : y;
    15 }
    16 int main (void) 
    17 {
    18   int a = 123, b = 456;
    19   decltype (max (a, b)) c;
    20   cout << typeid (a).name () << endl; // i
    21   decltype (max (&a, &b)) d = NULL;
    22   cout << typeid (d).name () << endl; // Pi
    23   // e:int&
    24   decltype (++a) e = a;
    25   --e; // --a;
    26   cout << a << endl; // 122
    27   // f:int
    28   decltype (b++) f = b;
    29   --f;
    30   cout << b << endl; // 456
    31   // g:int&
    32   decltype (a = b) g = a;
    33   --g;
    34   cout << a << endl; // 121
    35   // h:int
    36   decltype (b + a) h = b;
    37   --h;
    38   cout << b << endl; // 456
    39   // i:int
    40   decltype (a) i = a;    
    41   // j:int&
    42   decltype ((a)) j = a;//decltype的表达式如果是加上了括号的变量,结果将是引用
    43   cout << &i << ' ' << &j << ' ' << &a << endl;
    44   return 0;
    45 }

    注意:decltype((variable))(注意是双层括号)的结果永远是引用,
    而decltype(variable)的结果只有当variable本身是一个引用时才是引用

    3.何时使用decltype

    #include <iostream>
    #include <vector>
    #include <list>
    #include <map>
    using namespace std;
    template<typename C>
    void print(C& c)
    {
        for (decltype (c.begin()) it = c.begin(); it != c.end(); ++it)
            cout << *it << ' ';
        cout << endl;
    }
    int main(void) 
    {
        int ai[] = { 10, 20, 30, 40, 50 };
        vector<int> vi(ai, ai + 5);
        print(vi);
        list<int> const li(vi.begin(), vi.end());
        print(li);
        map<string, vector<int> > msv;
        msv["张飞"].push_back(70);
        msv["张飞"].push_back(85);
        msv["赵云"].push_back(75);
        msv["赵云"].push_back(90);
        msv["关羽"].push_back(80);
        msv["关羽"].push_back(95);
        // .
        // .
        // .
        // 此处省略15000行代码
        // .
        // .
        // .
        //    int sum = 0;
        //key_type就表示map中key的类型,value_type表示具体值的类型,mapped_type表示map中value(pair)的类型
        decltype (msv)::mapped_type::value_type sum = 0;
        for (size_t i = 0; i < msv["张飞"].size(); ++i)
            sum += msv["张飞"][i];
        cout << sum << endl;
        return 0;
    }

    4.auto和decltype结合使用,返回类型后置

    #include <iostream>
    #include <typeinfo>
    using namespace std;
    double foo(int arg)
    {
        return arg / 2.0;
    }
    int foo(double arg) 
    {
        return int(arg * 2);
    }
    // 返回类型后置
    template<typename T>
    auto bar(T const& arg) -> decltype (foo(arg)) 
    {
        return foo(arg);
    }
    // 返回类型后置
    template<typename T>
    auto add(T const& x, T const& y) -> decltype (x + y) 
    {
        return x + y;
    }
    
    class Point 
    {
    public:
        Point(int x, int y) : m_x(x), m_y(y) {}
        void draw(void) const
        {
            cout << "点(" << m_x << ',' << m_y << ')' << endl;
        }
    private:
        int m_x, m_y;
    };
    
    class Line 
    {
    public:
        Line(Point const& p1, Point const& p2) :m_p1(p1), m_p2(p2) {}
        void draw(void) const
        {
            cout << "线(" << '	';m_p1.draw();
            cout << '	';
            m_p2.draw();
            cout << ')' << endl;
        }
    private:
        Point m_p1, m_p2;
    };
    
    Line const operator+ (Point const& p1, Point const& p2) 
    {
        return Line(p1, p2);
    }
    int main(void) 
    {
        cout << bar(1) << endl; // 0.5
        cout << bar(0.5) << endl; // 1
        Point p1(100, 200), p2(300, 400);
        Line line = add(p1, p2);
        line.draw();
        return 0;
    }
  • 相关阅读:
    zabbix添加自定义监控项
    文件的时间属性(摘自网友的博客)
    svn从Windows服务器上迁移到Linux上
    modelsim 保存波形文件
    Viso Professional 2013版本激活(office 系列产品 -- visio 2013 / project 2013 破解工具
    kindle paperwhite3 连不上WIFI解决方法
    TotoiseSVN的基本使用方法
    SVN 版本服务器搭配全过程详解(含服务端、客户端)
    modelsim读写TXT文件
    如何对多个文件进行MODELSIM仿真? (由于是一个很大的项目,不可能把所有MODULE都放在一个文件里。 如何在ModelSim中对多个.V文件进行仿真?)
  • 原文地址:https://www.cnblogs.com/LuckCoder/p/8467634.html
Copyright © 2020-2023  润新知