亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

C++模板元編程和編寫模板有什么區別?

C++模板元編程和編寫模板有什么區別?

C++
蠱毒傳說 2018-07-19 14:26:46
C++模板元編程和編寫模板有什么區別?什么是模板元編程?應用場景主要有哪些?
查看完整描述

2 回答

?
胡說叔叔

TA貢獻1804條經驗 獲得超8個贊

很多回答都是復制粘貼一段沒有什么用處的。我來說幾句,如果lz滿意,希望采納,鼓勵下誠實原創的回答。如果不滿意,歡迎追問。

模板元編程的意思是使用模板實現元編程,它的內涵比模版本身(java稱為泛型)大得多。模版可以看作元編程最基本的運用。
所謂元編程,就是編寫一個用來編程的程序(生成代碼的程序),元xx(英文meta-xxx)就是xxx的xxx。比如,元學習就是學習如何學習的方法,元數據就是描述數據的數據,等等。

C++的模版之所以可以用來作為代碼生成器,是因為它是圖靈完備的,也就是說,它可以實現一切編程語言能實現的功能,關鍵的一條是,C++的模版可以定義參數變量。而不僅僅是類型。
比如
計算1+2+3...+100
我們可以不用循環,只用遞歸實現,那就是
給定一個n=100,我們可以讓機器生成如下代碼:
int sum_n_1()
{
return 100 + sum_n_2();
}
注意sum_n_2這個函數也不存在,但是我們可以繼續生成這么一個函數
int sum_n_2()
{
return 99 + sum_n_3();
}
...
直到生成一個
int sum_n_100()
{
return 1;
}
那么要計算1+2+3...+100,如果機器生成了以上100個函數,我們只要調用sum_n_1()是不是就算出來了呢?
這個過程關鍵是這100個函數,是自動生成的,而不是我們自己一個一個寫的。用C++模版得到如下代碼:

#include <iostream>

template<typename T, int i=1>
class someComputing {
public:
    typedef volatile T* retType; // 類型計算
    enum { retValume = i + someComputing<T, i-1>::retValume }; // 數值計算,遞歸
    static void f() { std::cout << "someComputing: i=" << i << '\n'; }
};
template<typename T> // 模板特例,遞歸終止條件
class someComputing<T, 0> {
public:
    enum { retValume = 0 };
};

template<typename T>
class codeComputing {
public:
    static void f() { T::f(); } // 根據類型調用函數,代碼計算
};

int main(){
    someComputing<int>::retType a=0;
    std::cout << sizeof(a) << '\n'; // 64-bit 程序指針
    // VS2013 默認最大遞歸深度500,GCC4.8 默認最大遞歸深度900(-ftemplate-depth=n)
    std::cout << someComputing<int, 500>::retValume << '\n'; // 1+2+...+500
    codeComputing<someComputing<int, 99>>::f();
    std::cin.get(); return 0;
}

就可以實現生成代碼的功能。
因為這個過程完全是編譯器做的,所以最后生成的計算1+2+3...+100
會自動展開函數,得到5050,也就是結果。
那么顯然當程序運行的時候,直接就輸出結果了,程序不需要再求和。求和的過程提前到編譯階段就完成了。

我們可以用解釋語言來類比:
解釋語言實現了運行的時候編譯
元編程實現了編譯的時候運行。


查看完整回答
1 反對 回復 2018-07-27
  • 2 回答
  • 0 關注
  • 1396 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號