模板元編程

模板超編程(英語:Template metaprogramming,縮寫:TMP)是一種超編程技術,編譯器使用模板產生暫時性的源碼,然後再和剩下的源碼混合並編譯。這些模板的輸出包括編譯時期常數資料結構以及完整的函式。如此利用模板可以被想成編譯期的執行。這種技術被許多語言使用,最為知名的當屬C++,其他還有CurlDEiffel,以及语言扩展,如Template Haskell英语Template Haskell

模板元编程的构成要素

使用模板作為元编程的技術需要兩階段的操作。首先,模板必須被定義;第二,定義的模板必須被實體化才行。 模板的定義描述了生成源碼的一般形式,而使實體化則導致了某些源碼的組合根據該模板而生成。

模板元編程是一般性地圖靈完全Turing-complete),這意味著任何可被電算軟體表示的運算都可以透過模板超編程以某種形式去運算。

模板與巨集macros)是不同的。所謂巨集只不過是以文字的操作及替換來生成程式碼,雖然同為編譯期的語言特色,但巨集系統通常其編譯期處理流的能力(compile-time process flow abilities)有限,且對其所依附之語言的語義及型別系統缺乏認知(一个例外是LISP的巨集)。

模板元編程沒有可變的變數——也就是說,變數一旦初始化後就不能夠改動。因此他可以被視為函數式編程functional programming)的一種形式。

使用模板超編程

模板超編程的語法通常與一般的程式語法迥異,他有其實際的用途。一些使用模板超編程的共同理由是為了實現泛型編程generic programming)或是展現自動編譯期最佳化,像是只要在編譯期做某些事一次就好,而無需每次程式執行時去做。

編譯期類別生成

以下將展示究竟何謂"編譯期程式設計"。階乘是一個不錯的例子,在此之前我們先來回顧一下一般C++中階乘函式的遞迴寫法:

int factorial(int n) 
{
    if (n == 0)
       return 1;
    return n * factorial(n - 1);
}

void foo()
{
    int x = factorial(4); // == (4 * 3 * 2 * 1 * 1) == 24
    int y = factorial(0); // == 0! == 1
}

以上的程式碼會在程式執行時才決定4和0的階乘。

現在讓我們看看使用了模板超編程的寫法,模板特化提供了"遞迴"的結束條件。這些階乘可以在編譯期完成計算。以下源碼:

template <int N>
struct Factorial 
{
    enum { value = N * Factorial<N - 1>::value };
};

template <>
struct Factorial<0> 
{
    enum { value = 1 };
};

// Factorial<4>::value == 24
// Factorial<0>::value == 1
void foo()
{
    int x = Factorial<4>::value; // == 24
    int y = Factorial<0>::value; // == 1
}

程式碼如上在編譯時期計算4和0的階乘值,使用該結果值彷彿他們是預定的常數一般。

雖然從程式功能的觀點來看,這兩個版本很類似,但前者是在執行期計算階乘,而後者卻是在編譯期完成計算。 然而,為了能夠以此方式使用模板,編譯器必須在編譯期知道模板的參數值,也就是Factorial<X>::value只有當X在編譯期已知的情況下才能使用。換言之,X必須是常數(constant literal)或是常數表示式(constant expression),像是使用sizeof運算子。

編譯期程式碼最佳化

以上階乘的範例便是編譯期程式碼最佳化的一例,該程式中使用到的階乘在編譯期時便被預先計算並作為數值常數植入執行碼當中,節省了執行期的經常開銷(計算時間)以及記憶體足跡(memory footprint)。

編譯期迴圈展開(loop-unrolling)是一個更顯著的例子,模板超編程可以被用來產生n維(n-dimensional)的向量類別(當然n必須在編譯期已知)。與傳統n維向量比較,他的好處是迴圈可以被展開,這可以使性能大幅度提升。考慮以下例子,n維向量的加法可以被寫成:

template <int dimension>
Vector<dimension>& Vector<dimension>::operator+=(const Vector<dimension>& rhs) 
{
    for (int i = 0; i < dimension; ++i)
        value[i] += rhs.value[i]
    return *this;
}

當編譯器實體化以上的模板函式,可能會生成如下的程式碼:

template <>
Vector<2>& Vector<2>::operator+=(const Vector<2>& rhs) 
{
    value[0] += rhs.value[0]
    value[1] += rhs.value[1]
    return *this;
}

因為模板參數dimension在編譯期是常數,所以編譯器應能展開for迴圈。

靜態多型

多型是一項共通的標準編程工具,衍生類別物件可以被當作基礎類別的物件之實體使用,但能夠呼叫衍生物件的函式,或稱方法(methods),例如以下的程式碼:

class Base
{
    public:
    virtual void method() { std::cout << "Base"; }
};

class Derived : public Base
{
    public:
    virtual void method() { std::cout << "Derived"; }
};

int main()
{
    Base *pBase = new Derived;
    pBase->method(); //outputs "Derived"
    delete pBase;
    return 0;
}

喚起的 virtual 函式是屬於位於繼承最下位之類別的。這種動態多型(dynamically polymorphic)行為是藉由擁有虛擬函式的類別所產生的虛擬函式表(virtual look-up tables英语Virtual method table)來實行的。虛擬函式表會在執行期被查找,以決定該喚起哪個函式。因此動態多型無可避免地必須承擔這些執行期成本。

然而,在許多情況下我們需要的僅是可以在編譯期決定,無需變動的多型行為。那麼一來,奇怪的遞迴模板樣式(Curiously Recurring Template Pattern CRTP)便可被用來達成靜態多型。如下例:

template <class Derived>
struct base
{
    void interface()
    {
         // ...
         static_cast<Derived*>(this)->implementation();
         // ...
    }
};

struct derived : base<derived>
{
     void implementation();
};

這裡基礎類別模板有著這樣的優點:成員函式的本體在被他們的宣告之前都不會被實體化,而且它可利用 static_cast 並透過自己的函式來使用衍生類別的成員,所以能夠在編譯時產生出帶有多型特性的物件複合物。在現實使用上,Boost迭代器库[1]页面存档备份,存于互联网档案馆)便有採用 CRTP 的技法。

其他類似的使用還有"Barton–Nackman trick英语Barton–Nackman trick",有時候被稱作"有限制的模板擴張",共同的功能被可以放在一個基礎類別當中,作為必要的構件使用,以此確保在縮減多餘程式碼時的一致行為。

模板超編程的優缺點

  • 編譯期對執行期:因為模板的運算以及展開都是在編譯期,這會花相對較長的編譯時間,但能夠獲得更有效率的執行碼。編譯期花費一般都很小,但對於大專案或是普遍依賴模板的程式,也許會造成很大的編譯開銷。
  • 泛型程式設計:模板超編程允許程式設計師專注在架構上並委託編譯器產生任何客戶碼要求的實作。因此,模板超編程可達成真正的泛用程式碼,促使程式碼縮小並較好維護。
  • 可讀性:對於C++來說,模板超編程的語法及語言特性比起傳統的C++編程,較難以令人理解。因此對於那些在模板超編程經驗不丰富的程式設計師來說,程式可能會變的難以維護。(這要視各語言對於模板超編程語法的實作)
  • 移植性:對於C++來說,由於各編譯器的差異,大量依賴模板超編程(特別是最新形式的)的程式碼可能會有移植性的問題。

關聯項目

參照

外部連結


Read other articles:

H.M. Husni DjibrilB.ScBupati Sumbawa ke-10Masa jabatan17 Februari 2016 – 17 Februari 2021PresidenJoko WidodoGubernurMuhammad Zainul MajdiZulkieflimansyahWakilMahmud AbdullahPendahuluJamaluddin MalikPenggantiHasan Basri (Plh.) Informasi pribadiLahir(1955-05-06)6 Mei 1955Utan, Sumbawa, Sunda Kecil, IndonesiaMeninggal10 Maret 2021(2021-03-10) (umur 65)Tangerang, Banten, IndonesiaPartai politikPartai Demokrasi Indonesia (1984-1999)Partai Demokrasi Indonesia Perjuangan (1999-20...

Imamat 1Pasal pertama kitab Imamat pada edisi ke-6 Mikraot Gedolot (Alkitab rabbinik), terbitan tahun 1618-1619.KitabKitab ImamatKategoriTauratBagian Alkitab KristenPerjanjian LamaUrutan dalamKitab Kristen3← Keluaran 40 pasal 2 → Imamat 1 adalah pasal pertama dari Kitab Imamat dalam Alkitab Ibrani dan Perjanjian Lama di Alkitab Kristen. Termasuk dalam kumpulan kitab Taurat yang disusun oleh Musa.[1][2] Teks Naskah sumber utama: Masoretik, Gulungan En-Gedi, Taurat S...

Quinto Vicentino Entidad subnacional Quinto VicentinoLocalización de Quinto Vicentino en Italia Coordenadas 45°34′00″N 11°37′00″E / 45.566666666667, 11.616666666667Capital Quinto VicentinoIdioma oficial ItalianoEntidad Comuna de Italia • País Italia • Región Véneto • Provincia VicenzaFracciones Lanzè, Valproto, Villaggio Monte GrappaMunicipios limítrofes Bolzano Vicentino, Gazzo (PD), San Pietro in Gu (PD), Torri di Quartesolo, VicenzaSuper...

Bilanz Teilnehmende Rundfunkanstalt Erste Teilnahme 2007 Anzahl der Teilnahmen 15 (Stand 2023) Höchste Platzierung 9 (2010, 2011) Höchste Punktzahl 136 (2010) Niedrigste Punktzahl 15 (2014 SF) Punkteschnitt (seit erstem Beitrag) 72,25 (Stand 2019) Punkteschnitt pro abstimmendem Land im 12-Punkte-System 1,50 (Stand 2019) Dieser Artikel befasst sich mit der Geschichte Georgiens als Teilnehmer am Eurovision Song Contest. Inhaltsverzeichnis 1 Regelmäßigkeit der Teilnahme und Erfolge im Wettbe...

Polish footballer Emilia Zdunek Personal informationDate of birth (1992-09-12) 12 September 1992 (age 31)[1]Place of birth Szczecin, Poland[2]Height 1.65 m (5 ft 5 in)Position(s) Midfielder[1]Team informationCurrent team Górnik ŁęcznaNumber 24Youth career2002–2007 UKS Victoria SP 2 SianówSenior career*Years Team Apps (Gls)2007–2008 UKS Victoria SP 2 Sianów 2[3] (1)2008–2013 Pogoń Women Szczecin 49[4] (23)2013 Unia Racibó...

Pemandangan udara dari All England Lawn Tennis and Croquet Club All England Lawn Tennis and Croquet Club,[1] juga dikenal sebagai All England Club,[2] adalah klub anggota pribadi. Tempat ini paling dikenal sebagai tempat Kejuaraan Wimbledon, satu-satunya acara tenis Grand Slam yang masih diadakan di atas rumput. Awalnya acara amatir yang dihadiri anggota klub dan teman-teman mereka selama beberapa hari setiap musim panas, kejuaraan menjadi jauh lebih menonjol daripada klub itu...

GNU software testing framework Not to be confused with DjVu, a computer file format for storing scanned documents. This article has multiple issues. Please help improve it or discuss these issues on the talk page. (Learn how and when to remove these template messages) The topic of this article may not meet Wikipedia's notability guidelines for products and services. Please help to demonstrate the notability of the topic by citing reliable secondary sources that are independent of the topic an...

Schronisko w Górze Smoleń Drugie Plan jaskini Państwo  Polska Województwo  śląskie Położenie Salceson, Park Jurajski Właściciel Lasy Państwowe Długość 5,5 m Głębokość 1,5 m Wysokość otworów 440 m n.p.m. Ekspozycja otworów ku NE Kod J.Cz.IV-04.32 Położenie na mapie gminy PilicaSchronisko w Górze Smoleń Drugie Położenie na mapie PolskiSchronisko w Górze Smoleń Drugie Położenie na mapie województwa śląskiegoSchronisk...

Period of the United States expansion It has been suggested that The United States and the French Revolutionary and Napoleonic Wars be merged into this article. (Discuss) Proposed since October 2023. The United States of America1789–1849The Star Spangled Banner flag (1795–1818)LocationUnited StatesIncludingFederalist EraJeffersonian EraEra of Good FeelingsJacksonian EraIndustrial RevolutionMigrations:American frontierMormon pioneersWestward Expansion TrailsPresident(s)George WashingtonJoh...

Fictional supernatural being Fictional character The OutsiderDishonored characterThe Outsider as he appears in Dishonored 2First appearanceThe Hand that Feeds (The Tales from Dunwall, 2012)First gameDishonored (2012)Last appearanceDeath of the Outsider (2017)Created byArkane StudiosVoiced byBilly Lush (Dishonored)Robin Lord Taylor (Dishonored 2, Dishonored: Death of the Outsider) The Outsider is a fictional supernatural being in Arkane Studios' Dishonored franchise, residing in an empty other...

Former railway station in Victoria, Australia RobinvaleTrack side of the Robinvale station buildingGeneral informationLine(s)RobinvalePlatforms1Tracks1Other informationStatusClosedHistoryOpened1924ClosedTo passengers on 3 June 1978Services Preceding station   Disused railways   Following station Bannerton   Robinvale line   Terminus   List of closed railway stations in Victoria   Robinvale station in Robinvale, Victoria, Australia, is the terminus of the Robinval...

本條目存在以下問題,請協助改善本條目或在討論頁針對議題發表看法。 此條目需要精通或熟悉相关主题的编者参与及协助编辑。 (2015年1月16日)請邀請適合的人士改善本条目。更多的細節與詳情請參见討論頁。 此條目需要补充更多来源。 (2015年1月16日)请协助補充多方面可靠来源以改善这篇条目,无法查证的内容可能會因為异议提出而被移除。致使用者:请搜索一下条目的...

Nizar ChaariNizar Chaari in 2020Born (1977-06-11) 11 June 1977 (age 46)Sfax, TunisiaOccupation(s)Television and radio producer/presenter Nizar Chaari (Arabic: نزار الشعري), (born June 11, 1977 in Sfax), is a Tunisian radio and television presenter and producer. He is best known for his interviews with various Tunisian and Arabic world celebrities, particularly musicians and film/television stars and directors. Radio career Radio Sfax Chaari began in the media business in 1993 a...

2005 video game 2005 video gameThe Stalin SubwayDeveloper(s)G5 SoftwarePublisher(s)Buka EntertainmentDesigner(s)Nikolay SitnikovSeriesThe Stalin SubwayEngineOrion EnginePlatform(s)Microsoft WindowsReleaseRUS: September 29, 2005Genre(s)First-person shooterThe Stalin Subway (Russian title Метро-2, Metro-2) is a first-person shooter video game developed by G5 Software and Orion Games. It was published by Buka Entertainment in Russia in September 2005 and in the United States in October of t...

Maro Sebo UluKecamatanMasjid NurussolihinNegara IndonesiaProvinsiJambiKabupatenBatanghariPemerintahan • CamatIsmail. S.PdPopulasi (2020) • Total39.588 jiwaKode pos36652Kode Kemendagri15.04.06 Kode BPS1504011 Desa/kelurahan16 desa1 kelurahan Sungai Batanghari di Desa Kampung Baru, Maro Sebo Ulu sekitar tahun 1910-an. Maro Sebo Ulu adalah sebuah kecamatan di Kabupaten Batanghari, Jambi, Indonesia. Desa/Kelurahan Simp. Sungai Rengas Batu Sawar Peninjauan Teluk L...

Russian ski jumper Sofia TikhonovaСо́фья Ти́хоноваTikhonova in Hinzenbach, 2014Country RussiaFull nameSofia Dmitrievna TikhonovaBorn (1998-11-16) 16 November 1998 (age 25)Saint Petersburg, RussiaSki clubSaint Petersburg KOR1 DinamoWorld Cup careerSeasons2014–presentTeam podiums2Indiv. starts69Team starts2 Medal record Women's ski jumping Junior World Championships 2015 Almaty Individual NH 2015 Almaty Team NH 2016 Râșnov Individual NH 2018...

Brig-sloop of the Royal Navy For other ships with the same name, see HMS Doterel. Dotterell History United Kingdom NameHMS Doterel NamesakeEurasian dotterel Ordered31 December 1807 BuilderJohn Scott and Richard Blake, Bursledon[2] Laid downApril 1808 Launched6 October 1808 Honours andawardsNaval General Service Medal clasp Basque Roads 1809[1] FateBroken up 1855 General characteristics [2] TypeCruizer-class brig-sloop Tons burthen38611⁄94 (bm) Length 100 ft ...

American physical chemist Stephen LeoneAlma materNorthwestern University B.A. (1970) University of California, Berkeley Ph.D. (1974)Known forAttosecond Spectroscopy, Transient absorption spectroscopyScientific careerFieldsPhysical ChemistryInstitutionsUniversity of California, BerkeleyDoctoral advisorC. Bradley Moore Websitewww.cchem.berkeley.edu/leonegrp/ Stephen Robert Leone (born May 19, 1948) is an American physical chemist and the John R. Thomas Endowed Chair in Physical Chemis...

Deutsche Oper Berlin Openingsdatum 7 november 1912 (eerste gebouw)24 september 1961 (tweede gebouw) Locatie Bismarckstraße 34–37, Charlottenburg Berlijn,  Duitsland Coördinaten 52° 31′ NB, 13° 19′ OL Type Operagebouw Gebouw Architect Heinrich Seeling (eerste gebouw)Fritz Bornemann (tweede gebouw) Gebouwd 1911-1912 (eerste gebouw)1957-1961 (tweede gebouw) Overig Totale capaciteit 1859 zitplaatsen Lid van Berliner Opernstiftung Openbaar vervoer Deutsche Oper Officiële we...

Italian long-distance runner Maria CuratoloCuratolo at the Italian Athletics Clubs Championships in Treviso in 1988.Personal informationNational teamItaly: 24 caps (1984-1997)[1]Born12 October 1963 (1963-10-12) (age 60)Turin, ItalyHeight1.47 m (4 ft 10 in)Weight39 kg (86 lb)SportSportAthleticsEventLong-distance runningClubFiat Sud Formia[1]Achievements and titlesPersonal bests 3000 m: 9:01.71 (1988) 5000 m: 16:04.91 (1988) 10,000 m: 32:0...