當1994年,Erwin Unruh在C++標準委員會上演示了通過C++模板在編譯期計算素數的程序后,C++模板元編程的能力就已經被人們認識到了。但是由于函數式編程和廣大程序員所熟悉的命令式編程存在著較大差異,以及C++標準和C++編譯器對模板元編程支持上的很多漏洞,導致了模板元編程的代碼在一般程序員的眼中十分的晦澀難懂。所以隨后的很多年,模板元編程只被掌握在少數C++程序員手中,而在更大多數人眼中則更似是一種奇技淫巧。
雖然如此,由于人們對計算機程序的表達力和性能的同時追求,C++模板元編程的使用還是滲透在非常多優秀的框架和程序庫中。往往你看一個漂亮的C++庫或者框架的源碼,都會驚奇的發現,為其漂亮點睛、化腐朽為神奇的那段核心代碼中,都離不開模板元編程的身影。因為模板元編程的編譯期計算和代碼生成的能力,可以讓你的程序更加的靈活、簡潔、安全并且高效。
正是如此,C++標準庫STL中就使用了非常多的模板元編程技巧,而且也給程序員提供了很多好用的模板元編程工具,例如我們之前提到的豐富的type_traits
工具集。而boost中的mpl,則是一個完全為模板元編程打造的庫。它實現了完備的編譯期數據結構和算法,以及各種常用的元編程模式。Mpl甚至還實現了一套編譯期的lambda架構,用于在模板元編程中使用編譯期的lambda表達式。但是遺憾的是,mpl的實現過程中同時大量的使用了boost的預處理元編程技術,導致代碼非常的晦澀難懂,對想通過閱讀mpl源碼來學習模板元編程的同學增加了非常大的噪音干擾。
自從C++11標準發布后,C++語言和主流編譯器對模板以及編譯期計算的支持已經逐漸完備,同時標準修復了不少漏洞,使得模板元編程的代碼可以書寫的更加自然和簡單。為此,我基于C++11標準實現了一套針對C++模板元編程的基礎庫TLP。這個庫的主要目的是幫助大家更容易地學習C++模板元編程,正因如此我在寫的過程中不斷地追求代碼的表達力和清晰性。為了能夠通過測試用例來展示庫組件的用法,我專門編寫了一個面向模板元編程進行編譯期測試的xUnit測試框架,TLP庫中的所有組件都經過了該測試框架的測試。
雖然你的軟件可以直接依賴整個TLP庫,但是對于C++這么一門讓程序員追求極致的語言,學會TLP中模板元編程的設計技巧,然后按需所取地去解決自己的問題顯得更為實際。而且模板元編程的特點決定了它不應該出現在你軟件中的每一處,正常情況下只是在最核心地方去解決一些關鍵的問題。所以你應該把TLP庫當做一個素材庫,學習并掌握里面每個組件和算法的設計,學會針對你的具體問題采用類似的設計技巧去解決問題。為了讓大家能夠更好地學習TLP庫中的代碼設計,我寫了這篇手冊,介紹了模板元編程的基礎知識以及TLP庫中關鍵組件和算法的實現技巧,最后還列舉了模板元編程的一些具體應用。在這個手冊中,我同時提到了很多對編程語言和軟件設計的理解,希望也會對大家有用。
正如我最開始所說,模板元編程是中級C++程序員邁向高級的必經之路,希望本文以及TLP庫中的代碼對大家更好地學習模板元編程起到幫助,使得我們可以在C++中以一種更有效、更酷的方式去解決問題。
** 作者: MagicBowen**
** Email:e.bowen.wang@icloud.com **
** 轉載請注明作者信息,謝謝!**