是不是常常使用assert?是否對你開發過程帶來了便利?
void fun(TClass * p)
{
assert(p);
...
}
相信這樣的代碼不會陌生。但是,有沒有想過,這個assert只能用於運行期,而對於編譯期的錯誤就無能爲力了。或者,你比較熟悉boost,對於BOOST_STATIC_ASSERT比較熟悉。有沒有想過怎樣實現編譯期錯誤提示?
當我們寫了錯誤的代碼,編譯器會給我們提示,錯誤信息各種各樣。如果我們可以使用編譯器的這種功能,我們人工特意的做出一些功能,讓編譯器來識別,並且,還可以讓編譯器提示出錯。
實現這種功能,可以藉助於模板,藉助於模板的特化功能。下面來看看Loki是如何做的:
首先,聲明一個模板類:
template<int> struct CompileTimeError;
僅僅是聲明,並沒有進行定義。
下面進行特化
template<> struct CompileTimeError<true> {};
這樣,就有了一個CompileTimeError<true>類型的結構體定義。關鍵的代碼來了:
#define LOKI_STATIC_CHECK(expr, msg) \
{ Loki::CompileTimeError<((expr) != 0)> ERROR_##msg; (void)ERROR_##msg; }
其中,((expr) != 0返回一個bool值,這個值在編譯器是可以確定的。如果值爲true,那麼順利編譯通過;如果爲false,由於我們並沒有定義CompileTimeError<false>結構,編譯器無法找到匹配的類型,編譯無法通過。編譯器錯誤可能如下:error : 'ERROR_TEST' uses undefined struct 'CompileTimeError<__formal>'。
模板作爲C++一個重要組成部分,在平時開發中用的還很少,以後應該有效的使用起來。