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 << "線(" << '\t';m_p1.draw();
        cout << '\t';
        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;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM