<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                ## [$]一.模板參數 ### 1.模板參數 與函數參數類似,模板參數分為模板形參和模板實參。 + 對于函數模板,可以不顯式指定模板實參。但若編譯器無法推斷模板實參的類型,則需要指定模板實參。 + 對于類模板,必須指定模板實參。 ### 2.模板參數的作用域與可見性 1. 模板參數作用域開始:模板參數聲明之后 2. 模板參數作用域結束:模板聲明結束 3. 與任何其他名字一樣,模板參數會隱藏外層作用域中聲明的相同名字。 ```c++ template <typename T/*T作用域開始*/> T& max(const T& a,const T& b) { return a > b ? a : b; /*T作用域結束*/ } ``` ### 3.默認模板實參 1. 為類模板指定默認模板形參 ```c++ //聲明 template <typename T=int> class Array; //定義對象,尖括號不能省 Array<> a; ``` 2. \[11+\]為函數模板指定默認模板形參 ```c++ template <typename T=int> T& max(const T&,const T&); ``` ### 4.模板實參為模板 ```c++ template <typename T> class Array {}; class Matrix { private: Array<Array<int>> arr; }; ``` >[warning]VC++6.0的BUG: 兩個 `>` 之間要加一個空格,否則會被認為是運算符 ```c++ template <typename T> class Array {}; class Matrix { private: Array<Array<int> > arr; }; ``` ### [$]5.非類型模板參數(VC++6.0不支持) 1. 一個非類型模板參數表示一個值,而不是一個類型。 2. 非類型模板參數通常用于含有大小的復合類型,如指向數組的指針,數組的引用。 3. 非類型模板參數的模板實參必須是 **常量表達式** ,以保證編譯器正常實例化。 > VC++6.0不可運行下面案例 ```c++ template <unsigned N1, unsigned N2> int compare(const char (&p1)[N1], const char (&p2)[N2]) { return strcmp(p1, p2); } ``` ### [$]6.模板參數與作用域運算符 + 默認情況下,C++語言假定通過作用域運算符訪問的名字不是類型。 ```c++ template <typename T> T::type top() //T是一個類型名,而不是一個模板參數 { //code } ``` + 使用 `typename` 關鍵字指定通過作用域運算符訪問的名字含有模板參數: ```c++ template <typename T> typename T::type top() //T是一個類型名,而不是一個模板參數 { //code } ``` ## \[11+\][$]二.可變參數模板 ### 1.基本概念 1. **可變參數模板** 接受可變數目參數的模板函數或模板類。 2. **參數包** 可變數目的參數,只能獲取大小或拓展,不能直接求值或調用。存在兩種參數包: + 模板參數包:表示零個或多個模板參數 + 函數參數包:表示零個或多個函數參數 3. **拓展** 擴展一個包就是將它分解為構成的元素,對每個元素應用 **模式** ,獲得擴展后的列表。在模式右邊放一個省略號來觸發擴展操作。 4. **模式** 對參數包進行的處理。 ### 2.聲明一個可變參數模板 在模板參數名前添加省略號,表示模板參數包。在函數參數名前添加省略號,表示函數參數包。 ```c++ //Args是模板參數包 //expr是函數參數包 template <typename... args> void print(const args &... expr) { } ``` ### 3.sizeof...運算符 用于獲取包中的元素個數。不會對表達式求值,返回一個常量表達式。 #### 例1 ```c++ template <typename... args> void count(const args &... rest) { cout << "模板參數包的元素個數:" << sizeof...(args) << endl; cout << "函數參數包的元素個數:" << sizeof...(rest) << endl; } ``` 運行下面語句: ```c++ count(2, "4", 3.0, "8"); ``` >[test] >模板參數包的元素個數:4 >函數參數包的元素個數:4 ### 4.獲取參數包的內容 1. 可變參數函數通常是遞歸的,需要額外定義一個非可變參數的函數。在函數匹配時,非可變參數的函數優先匹配。 #### 例2 為了終止遞歸,需要先定義一個非可變參數的函數: ```c++ template <typename T> void print(const T &one) { cout << one << endl; } ``` 再來定義含參數包的函數: ```c++ template <typename T, typename... args> void print(const T &one, const args &... rest)//拓展args:模式為 const args & ,生成一個參數列表 { cout << one << endl; return print(rest...);//拓展rest:模式為 rest ,其中第一個參數會傳遞給 one,其余參數傳遞給 rest } ``` 運行下面語句: ```c++ print(2, "4", 3.0, "888"); ``` >[test] >2 >4 >3 >888 運行過程中的調用順序: | # | 函數 | 參數 `one` | 參數包 `rest` | |----|----|----|----| | 1|`print(2, "4", 3.0, "888")`|`2`|`"4", 3.0, "888"`| | 2 |`print("4", 3.0, "888")`|`"4"`|`3.0, "888"`| | 3|`print(3.0, "888")`|`3.0`|`"888"`| | 4|`print("888")`|`"888"`|空| #### 例3 假設有以下定義: ```c++ template <typename T> void print(const T &one) { cout << one << endl; } template <typename T, typename... args> void print(const T &one, const args &... rest) //拓展args:模式為 const args & ,生成一個參數列表 { cout << one << endl; return print(rest...); //拓展rest:模式為 rest ,其中第一個參數會傳遞給 one,其余參數傳遞給參數包 rest } //針對字符串的格式化,加上引號 const string format(const char *one) { return string("\"") + one + string("\""); } //針對其他類型的格式化 template <typename T> const T &format(const T &one) { return one; } template <typename... args> void format_print(const args &... exp) { print(format(exp)...);//拓展exp:拓展后每個參數均為 format(exp) } ``` 運行下面語句: ```c++ format_print(2, "4", 3.0, "888"); ``` >[test] >2 >"4" >3 >"888"
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看