溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

C++11新特性之變長參數(shù)模板的示例分析

發(fā)布時(shí)間:2021-08-26 17:27:16 來源:億速云 閱讀:301 作者:小新 欄目:開發(fā)技術(shù)

這篇文章主要為大家展示了“C++11新特性之變長參數(shù)模板的示例分析”,內(nèi)容簡而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領(lǐng)大家一起研究并學(xué)習(xí)一下“C++11新特性之變長參數(shù)模板的示例分析”這篇文章吧。

    C++11 變長參數(shù)模板

    在C++11之前,無論是類模板 還是函數(shù)模板,都只能按其指定的樣子,接受一組固定數(shù)量的模板參數(shù);

    這已經(jīng)大大提升了代碼的復(fù)用!

    在C++11之后,加入了新的表示方 法,允許任意個(gè)數(shù)、任意類別的模板參數(shù),同時(shí)也不需要在定義時(shí)將參數(shù)的個(gè)數(shù)固定。更加像”黑魔法“了。

    template<typename... Ts> class Magic;

    模板類 Magic 的對象,能夠接受不受限制個(gè)數(shù)的 typename 作為模板的形式參數(shù),例如下面的定義:

    class Magic<int,
    std::vector<int>,
    std::map<std::string,
    std::vector<int>>> darkMagic;

    既然是任意形式,所以個(gè)數(shù)為 0 的模板參數(shù)也是可以的:class Magic<> nothing;。 如果不希望產(chǎn)生的模板參數(shù)個(gè)數(shù)為 0,可以手動的定義至少一個(gè)模板參數(shù):

    template<typename Require, typename... Args> class Magic;

    變長函數(shù)參數(shù)包

    除了在模板參數(shù)中能使用 ... 表示不定長模板參數(shù)外,函數(shù)參數(shù)也使用同樣的表示法代表不定長參數(shù)。

    傳統(tǒng) C 中的 printf 函數(shù),雖然也能達(dá)成不定個(gè)數(shù) 的形參的調(diào)用,但其并非類別安全。而 C++11 除了能定義類別安全的變長參數(shù)函數(shù)外,還可以使類似 printf 的函數(shù)能自然地處理非自帶類別的對象。除了在模板參數(shù)中能使用 ... 表示不定長模板參數(shù)外, 函數(shù)參數(shù)也使用同樣的表示法代表不定長參數(shù),這也就為我們簡單編寫變長參數(shù)函數(shù)提供了便捷的手段, 例如:

    template<typename... Args> 
    void printf(const std::string &str, Args... args);

    其中,Args 與 args 分別代表模板與函數(shù)的變長參數(shù)集合, 稱之為參數(shù)包 (parameter pack)。參數(shù)包必須要和運(yùn)算符"..."搭配使用。

    如何解參數(shù)包

    長參數(shù)模板中,變長參數(shù)包無法如同一般參數(shù)在類或函數(shù)中使用;這個(gè)很好理解!

    因?yàn)樵跅V校覀冃枰戎篮瘮?shù)有多少個(gè)參數(shù),才可以入棧,但是我們不知道變長參數(shù)有多長,所以需要特殊手法!

    sizeof()獲得函數(shù)參數(shù)個(gè)數(shù)

    首先,我們可以使用 sizeof... 來計(jì)算參數(shù)的個(gè)數(shù),:

    template<typename... Ts>
    void magic(Ts... args) 
    {
        std::cout << sizeof...(args) << std::endl;
    }

    遞歸模板函數(shù)

    遞歸去獲得所有參數(shù),是非常容易想到的方法,這種方法不斷遞歸地向函數(shù)傳遞模板參數(shù),進(jìn)而達(dá)到遞歸遍歷所有模板參數(shù)的目的。

    printf 會不斷地遞歸調(diào)用自身:函數(shù)參數(shù)包 args... 在調(diào)用時(shí), 會被模板類別匹配分離為 T value和 Args... args。 直到 args... 變?yōu)榭諈?shù),則會與簡單的 printf(const char *s) 形成匹配,退出遞歸。

    //遞歸模板函數(shù)
    template<typename T0>
    void printf1(T0 value)
    {
        std::cout << value << std::endl;
    }
    template<typename T, typename... Ts>
    void printf1(T value, Ts... args) 
    {
        std::cout << value << std::endl;
        printf1(args...);
    }
    int RecursiveTemplateFunc() 
    {
        printf1(1, 2, "123", 1.1);
        return 0;
    }

    變參模板展開

    上面的遞歸很容易理解,但是比較繁瑣,那么還有沒有什么好方法呢?

    在 C++17 中增加了變參模板展開的支持,于是你可以在一個(gè)函數(shù)中完 成 printf 的編寫:

    //變參模板展開
    template<typename T0, typename... T>
    void printf2(T0 t0, T... t) 
    {
        std::cout << t0 << std::endl;
        if constexpr (sizeof...(t) > 0) 
            printf2(t...);
    }

    以上是“C++11新特性之變長參數(shù)模板的示例分析”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對大家有所幫助,如果還想學(xué)習(xí)更多知識,歡迎關(guān)注億速云行業(yè)資訊頻道!

    向AI問一下細(xì)節(jié)

    免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

    c++
    AI