<dfn id="7pnvb"><del id="7pnvb"><form id="7pnvb"></form></del></dfn>

      <form id="7pnvb"></form>

        <b id="7pnvb"><strike id="7pnvb"></strike></b>

          <form id="7pnvb"></form>
          現在的位置: 首頁 > 黃專家專欄 > 正文

          模板的 SFINAE 原則

          2014年10月30日 黃專家專欄 ⁄ 共 1704字 ⁄ 字號 評論關閉

          模板函數的重載遵循SFINAE原則(substitution-failure-is-not-an-error):當一個模板函數的返回值或參數類型無效的時候,該實例不會參與重載解析,也不會導致編譯錯誤。

          所以常用 is_same enable_if 等

          is_same 表示兩個類型是否相同 一般來說代碼是這樣實現的

          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          // stl 實現 4.1.2
          template<typename _Tp, _Tp __v>
          struct integral_constant {
            static const _Tp value = __v;
            typedef _Tp value_type;
            typedef integral_constant<_Tp, __v>   type;
          };
          typedef integral_constant<bool, true>     true_type;
          typedef integral_constant<bool, false>    false_type;
          
          // 定義了兩個不同的 class,其中的 value是其值,有true和false兩種
          
          template<typename, typename>
          struct is_same : public false_type { };
          
          // 模板的偏特化
          template<typename _Tp>
          struct is_same<_Tp, _Tp> : public true_type { };

          enable_if 表現的語義如下:

          enable_if?如果 bool 是true,那么其 type 定義為 T 否則無定義

          可能的實現如下:

          1
          2
          3
          4
          5
          6
          template<typename, bool>
          struct enable_if {};
          
          template<typename _Tp>
          struct enable_if<_Tp, true> {
            typedef _Tp type;
          };

          有了這以上兩個描述,我們演示一下模板的 SFINAE 原則:

          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          19
          20
          21
          22
          23
          24
          25
          26
          27
          28
          29
          30
          31
          32
          33
          34
          35
          36
          namespace test {
            template<typename _Tp, _Tp __v>
              struct integral_constant {
                static const _Tp value = __v;
                typedef _Tp value_type;
                typedef integral_constant<_Tp, __v>   type;
              };
          
            typedef integral_constant<bool, true>     true_type;
            typedef integral_constant<bool, false>    false_type;
          
            // 定義了兩個不同的 class,其中的 value是其值,有true和false兩種
            //
            template<typename, typename>
              struct is_same : public false_type { };
            //
            // 模板的偏特化
            template<typename _Tp>
              struct is_same<_Tp, _Tp> : public true_type { };
          
            template<bool, typename _Tp = void>
              struct enable_if {};
          
            template<typename _Tp>
              struct enable_if<true, _Tp> {
                typedef _Tp type;
              };
          }
          
          class SfinaeTest {
            public:
              void Foo(double) {
                std::cerr << "double" << std::endl;
              }
          
              template<class Tp>
                typename test::enable_if<test::is_same<Tp, int>::value || test::is_same<Tp, std::string>::value>::type
                Foo(Tp t) {
                  std::cerr << "Tp" << std::endl;
                }
          };
          
          int main() {
            SfinaeTest s;
            s.Foo(1);               // 成功,能夠推導出 Tp = int
            std::string str;        // 成功,能夠推導出 Tp = std::string
            s.Foo(1.0);             // 成功
          }

          抱歉!評論已關閉.

          新婚之夜我被十几个男人一起_60歳の熟女セックス_肚兜下的浑圆被揉捏np_漂亮的小峓子4在钱免费

              <dfn id="7pnvb"><del id="7pnvb"><form id="7pnvb"></form></del></dfn>

              <form id="7pnvb"></form>

                <b id="7pnvb"><strike id="7pnvb"></strike></b>

                  <form id="7pnvb"></form>