模板元程式設計(template metaprogramming)更準確的含義應該是「編『可以程式設計序的』程式」,而模板元程式(template metaprogram)則是「『可以程式設計序的』程式」。也就是說,我們給出**的產生規則,編譯器在編譯期解釋這些規則並生成新**來實現我們預期的功能。
讓我們來看乙個可以執行的模板元程式設計例子 — 計算給定整數的指定次方:
// xy.h
//原始摸板
templateclass xy;};
//用於終結遞迴的區域性特化版
templateclass xy;
};
模板元程式設計技術之根本在於遞迴模板例項化。第乙個模板實現了一般情況下的遞迴規則。當用一對整數來例項化模板時,模板xy需要計算其result_的值,將同一模板中針對例項化所得結果乘以x即可。第二個模板是乙個區域性特化版本,用於終結遞迴。
可以想象,如果我們以非常大的y值來例項化類模板xy,那肯定會占用大量的編譯器資源甚至會迅速耗盡可用資源(在計算結果溢位之前),因此,在實踐中我們應該有節制地使用模板元程式設計技術。
雖然 c++標準建議的最小例項化深度只有17層,然而大多數編譯器都能夠處理至少幾十層,有些編譯器允許例項化至數百層,更有一些可達數千層,直至資源耗盡。
模板元程式設計技術最早的實際應用之一是用於數值計算中的解迴圈。舉個例子,對乙個陣列進行求和的常見方法是:
// sumarray.h
template inline t sum_array(int dim, t* a)
return result;
}
這當然可行,但我們也可以利用模板元程式設計技術來解開迴圈:
// sumarray2.h
// 原始模板
template class sumarray
};// 作為終結準則的區域性特化版
template class sumarray<1, t>
};
用法如下:
// sumarraytest2.cpp
#include #include \"sumarray2.h\"
int main()
; std::cout << \" sumarray<6>(a) = \" << sumarray<6, int>::result(a);
}
當我們計算sumarray<6, int>::result(a)時,例項化過程如下:
sumarray<6, int>::result(a)
= a[0] + sumvector<5, int>::result(a+1)
= a[0] + a[1] + sumvector<4, int>::result(a+2)
= a[0] + a[1] + a[2] + sumvector<3, int>::result(a+3)[page]
= a[0] + a[1] + a[2] + a[3] + sumvector<2, int>::result(a+4)
= a[0] + a[1] + a[2] + a[3] + a[4] + sumvector<1, int>::result(a+5)
= a[0] + a[1] + a[2] + a[3] + a[4] + a[5]
可見,迴圈被展開為a[0] + a[1] + a[2] + a[3] + a[4] + a[5]。這種直截了當的展開運算幾乎總是比迴圈來得更有效率。
也許拿乙個有著600萬個元素的陣列來例證迴圈開解的優勢可能更有說服力。生成這樣的陣列很容易,有興趣,你不妨測試、對比一下。 結語
模板元程式設計技術首次正式亮相於todd veldhuizen的using c++ template metaprograms**之中。這篇文章首先發表於2023年5月的c++ report期刊上,後來stanley lippman編輯c++ gems一書時又收錄了它。參考文獻中給出了這篇文章的鏈結,它還描述了許多本文沒有描述到的內容。
**:
巨集元程式設計 技術 auto rec
auto rec巨集會快速探測滿足探測謂詞條件的 序號 最小的巨集。如果滿足條件會走實線深度往下探測,當遇到不滿足條件會走虛線。下面以探測16以內的 序號 define tl node 16 p tl if p 16 tl node 8,tl node 24 define tl node 8 p t...
元程式設計技術和動態編譯
什麼是元程式設計?執行時動態建立型別的功能稱為元程式設計。這個是.環境程式設計全景 中的定義 從學習uml就知道meta 的重要性了,再後來了解到mof metaobjectfacility 就更加著迷這個meta meta 在.之中.對於想真正了解乙個framework,了解它的meta東西是十分...
C 效能的程式設計技術
一 影響 c 效能的基本原理 1.i o 的開銷是最昂貴的 2.函式呼叫的開銷是乙個因素,因此我們應該內聯短小,頻繁呼叫的函式 3.複製物件的開銷是昂貴的。最好選擇按引用傳遞,而不是值傳遞。4.最好採用棧內建立物件,而不是採用堆建立物件 一般在堆內建立物件是在棧內建立物件花費的時間是 20備左右。5...