C++11 模板元編程 - 惰性


C++對模板的具現(xiàn)化采用盡量惰性的原則。只有當你使用了模板的內(nèi)部定義,編譯器才會為模板生成對應(yīng)的定義。

所以對于元函數(shù),當你不訪問內(nèi)部的Result對其求值,編譯器是不會為其做計算的。因此我們可以把一個元函數(shù)當做運行期函數(shù)指針一樣進行傳遞,直到我們需要的時候再對其求值。

對于惰性,我們來看下面這個例子:

template<typename T, bool isClonable>
struct Creator
{
    static T* create(const T* instance)
    {
        if(isClonable)
        {
            return instance->clone();
        }
        else
        {
            return new T(*instance);
        }
    }
};

如上我們希望有一個工廠類,用來創(chuàng)建入?yún)類型的對象。如果T支持clone方法,則采用從一個現(xiàn)有對象clone出新對象,否則調(diào)用拷貝構(gòu)造函數(shù)new出來一個新對象。Creator的第二個參數(shù)isClonable用來指示前一個參數(shù)T是否支持clone。

遺憾的是,上述代碼是不能工作的。當我們傳遞一個不支持clone的類形T進去,即使我們將isClonable設(shè)為false,編譯器也會對create函數(shù)進行完整編譯,會報告T缺少clone方法。

struct UnclonableObject
{
    UnclonableObject(){}
    UnclonableObject(const UnclonableObject&) {}
};

Creator<UnclonableObject, false> creator;

然而當我們寫出上述代碼進行編譯,發(fā)現(xiàn)卻能編譯通過!原因是C++編譯器的惰性特征做了手腳,此時它沒有看到任何人調(diào)用Creator<UnclonableObject, false>的create方法,所以并未生成該方法。

一旦我們寫出如下代碼,就會和我們最初預想的一致:編譯失敗,編譯器告訴我們UnclonableObject中沒有clone方法。

UnclonableObject object;
UnclonableObject* newObject = creator.create(&object);

解決該問題的方式很簡單,就是把使用if做運行期分支選擇的實現(xiàn)轉(zhuǎn)換成使用編譯期的分支選擇元函數(shù)__if()來實現(xiàn)。

template<typename T>
struct ClonableCreator
{
    static T* create(const T* instance)
    {
        return instance->clone();
    }
};

template<typename T>
struct UnclonableCreator
{
    static T* create(const T* instance)
    {
        return new T(*instance);
    }
};

template<typename T, bool isClonable> using Creator = __if(__bool(isClonable), ClonableCreator<T>, UnclonableCreator<T>);

由于模板元編程的惰性特征,__if()元函數(shù)會根據(jù)第一個入?yún)⒌腷ool值,對后面的兩個參數(shù)中的一個進行求值。因此當我們調(diào)用Creator<UnclonableObject, false>時,__if(__bool(false), ClonableCreator<T>, UnclonableCreator<T>)只會對UnclonableCreator<T>具現(xiàn)化,所以沒有再出現(xiàn)之前的編譯錯誤。

利于惰性求值,在編譯期選擇性的做類型具現(xiàn)化,是模板元編程非常有用的特性之一。


鴨子類型

返回 C++11模板元編程 - 目錄

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容