久久久久久久av_日韩在线中文_看一级毛片视频_日本精品二区_成人深夜福利视频_武道仙尊动漫在线观看

    1. <i id='brau2'><tr id='brau2'><dt id='brau2'><q id='brau2'><span id='brau2'><b id='brau2'><form id='brau2'><ins id='brau2'></ins><ul id='brau2'></ul><sub id='brau2'></sub></form><legend id='brau2'></legend><bdo id='brau2'><pre id='brau2'><center id='brau2'></center></pre></bdo></b><th id='brau2'></th></span></q></dt></tr></i><div class="qwawimqqmiuu" id='brau2'><tfoot id='brau2'></tfoot><dl id='brau2'><fieldset id='brau2'></fieldset></dl></div>
      <legend id='brau2'><style id='brau2'><dir id='brau2'><q id='brau2'></q></dir></style></legend>
        <bdo id='brau2'></bdo><ul id='brau2'></ul>

      <small id='brau2'></small><noframes id='brau2'>

      <tfoot id='brau2'></tfoot>

        為什么我可以從派生類調用基模板類方法

        Why can I call base template class method from derived class(為什么我可以從派生類調用基模板類方法)
          <bdo id='4oBch'></bdo><ul id='4oBch'></ul>

            <i id='4oBch'><tr id='4oBch'><dt id='4oBch'><q id='4oBch'><span id='4oBch'><b id='4oBch'><form id='4oBch'><ins id='4oBch'></ins><ul id='4oBch'></ul><sub id='4oBch'></sub></form><legend id='4oBch'></legend><bdo id='4oBch'><pre id='4oBch'><center id='4oBch'></center></pre></bdo></b><th id='4oBch'></th></span></q></dt></tr></i><div class="qwawimqqmiuu" id='4oBch'><tfoot id='4oBch'></tfoot><dl id='4oBch'><fieldset id='4oBch'></fieldset></dl></div>
            <tfoot id='4oBch'></tfoot>
            1. <small id='4oBch'></small><noframes id='4oBch'>

            2. <legend id='4oBch'><style id='4oBch'><dir id='4oBch'><q id='4oBch'></q></dir></style></legend>
                  <tbody id='4oBch'></tbody>

                • 本文介紹了為什么我可以從派生類調用基模板類方法的處理方法,對大家解決問題具有一定的參考價值,需要的朋友們下面隨著小編來一起學習吧!

                  問題描述

                  限時送ChatGPT賬號..

                  我決定測試Effective C++"中的一個示例,但沒有得到預期的結果.所以,顯然這個(簡化的)代碼不應該編譯:

                  I decided to test one of the examples in "Effective C++" and I'm not getting the result I expected. So, apparently this (simplified) code shouldn't compile:

                  template <class T>
                  struct A {
                      void f(){}
                  };
                  
                  template <class T>
                  struct B : public A <T> {
                      void f2() { f(); }   // calling base function - will not compile
                  };
                  

                  以下是解釋(為了簡單起見,類名已更改):

                  Here's the explanation (class names changed for simplicity) :

                  上面的代碼不能編譯,至少在符合標準的編譯器中不能.這樣的編譯器會抱怨 f 不存在.我們可以看到 f 在基類中,但編譯器不會在那里尋找它.

                  The code above won't compile, at least not with conformant compilers. Such compilers will complain that f doesn't exist. We can see that f is in the base class, but compilers won't look for it there.

                  我們需要了解原因.問題是當編譯器遇到類模板 B 的定義時,它們不知道它繼承自哪個類.當然,它是 A,但 T 是一個模板參數,一個直到以后才會知道(當 B 被實例化時).不知道什么T也就是說,沒有辦法知道 A<T> 類是什么樣的.特別是,沒有辦法知道它是否有 f 函數.

                  We need to understand why. The problem is that when compilers encounter the definition for the class template B, they don't know what class it inherits from. Sure, it's A<T>, but T is a template parameter, one that won't be known until later (when B is instantiated). Without knowing what T is, there's no way to know what the class A<T> looks like. In particular, there's no way to know if it has a f function.

                  我的編譯器 (Visual Studio) 不介意...它甚至不顯示任何警告.

                  My compiler (Visual Studio) doesn't mind... It doesn't even show any warnings.

                  以上代碼是否正確?

                  推薦答案

                  template <class T>
                  struct A {
                      void f(){}
                  };
                  
                  template <class T>
                  struct B : public A <T> {
                      void f2() { f(); }   // calling base function - will not compile
                  };
                  

                  在派生模板中,表達式 f() 不依賴于任何模板參數,因此編譯器會在第一階段查找期間嘗試解析它.此時,模板還沒有用類型實例化,編譯器不會查看基本的 A<T>.原因是編譯器不可能知道對于實例化的類型是否存在可能不包含任何成員的 A 特化.

                  In the derived template, the expression f() is not dependent on any template argument, so the compiler attempts to resolve it during the first phase lookup. At this point, the template has not yet been instantiated with the type, and the compiler won't look into the base A<T>. The reason is that the compiler could not possibly know whether for the type of the instantiation there is a specialization of A<T> that might not contain any members.

                  解決方案是使表達式依賴,最簡單的方法是使用 this-> 進行限定:

                  The solution is to make the expression dependent, the simplest way would be to qualify with this->:

                  template <typename T>
                  void B<T>::f2() {  this->f(); }
                  

                  由于表達式現在是相關的,查找被延遲到第二階段,在該階段替換類型并且 A 是一個具體類型.另一種選擇是使用定義它的類進行限定:

                  As the expression is now dependent, lookup is delayed until the second phase, where the type is substituted and A<T> is a concrete type. Another alternative is qualifying with the class where it is defined:

                  template <typename T>
                  void B<T>::f2() { A<T>::f(); }
                  

                  再次表達變得依賴,并將在第二階段解決.主要區別在于,在第二種情況下,調用是合格的,因此它不使用動態調度.如果 A<T>::f() 是虛擬的,它仍然會執行 A<T>::f(),而不是最終的覆蓋.

                  Again the expression becomes dependent and will be resolved during the second phase. The main difference is that in this second case, the call is qualified and thus it does not use dynamic dispatch. If A<T>::f() was virtual it would still execute A<T>::f(), and not the final overrider.

                  代碼正確嗎?不.VS 接受嗎?是的.

                  Is the code correct? No. Does VS accept it? Yes.

                  這是 Visual Studio 編譯器中已知的不符合項,未實現兩階段查找.它將模板內的所有查找延遲到第二階段,此時查找成功.

                  This is a known non-conformance in the Visual Studio compiler, that does not implement two phase lookup. It delays all lookup inside the template to the second phase and at that point lookup succeeds.

                  這篇關于為什么我可以從派生類調用基模板類方法的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!

                  【網站聲明】本站部分內容來源于互聯網,旨在幫助大家更快的解決問題,如果有圖片或者內容侵犯了您的權益,請聯系我們刪除處理,感謝您的支持!

                  相關文檔推薦

                  Why do two functions have the same address?(為什么兩個函數的地址相同?)
                  Why the initializer of std::function has to be CopyConstructible?(為什么 std::function 的初始化程序必須是可復制構造的?)
                  mixing templates with polymorphism(混合模板與多態性)
                  When should I use the keyword quot;typenamequot; when using templates(我什么時候應該使用關鍵字“typename?使用模板時)
                  Dependent name resolution amp; namespace std / Standard Library(依賴名稱解析命名空間 std/標準庫)
                  gcc can compile a variadic template while clang cannot(gcc 可以編譯可變參數模板,而 clang 不能)

                  <small id='Z3WYa'></small><noframes id='Z3WYa'>

                    <bdo id='Z3WYa'></bdo><ul id='Z3WYa'></ul>
                  • <tfoot id='Z3WYa'></tfoot>

                    <i id='Z3WYa'><tr id='Z3WYa'><dt id='Z3WYa'><q id='Z3WYa'><span id='Z3WYa'><b id='Z3WYa'><form id='Z3WYa'><ins id='Z3WYa'></ins><ul id='Z3WYa'></ul><sub id='Z3WYa'></sub></form><legend id='Z3WYa'></legend><bdo id='Z3WYa'><pre id='Z3WYa'><center id='Z3WYa'></center></pre></bdo></b><th id='Z3WYa'></th></span></q></dt></tr></i><div class="qwawimqqmiuu" id='Z3WYa'><tfoot id='Z3WYa'></tfoot><dl id='Z3WYa'><fieldset id='Z3WYa'></fieldset></dl></div>
                        <tbody id='Z3WYa'></tbody>

                          • <legend id='Z3WYa'><style id='Z3WYa'><dir id='Z3WYa'><q id='Z3WYa'></q></dir></style></legend>
                            主站蜘蛛池模板: 亚洲精选一区二区 | 国产欧美一区二区三区另类精品 | 岛国在线免费观看 | 91视频久久久久 | 亚州精品成人 | 国产成人综合一区二区三区 | 看特级黄色片 | 欧美日韩中 | 成人av网页 | 网络毛片| 久久精品一区二区三区四区 | 亚洲福利精品 | 美女国内精品自产拍在线播放 | 精品久久久一区 | 亚洲国产一区二区在线 | 亚洲成网站 | 成人av免费网站 | 亚洲福利一区 | 亚洲精品日韩精品 | 羞羞视频网站免费观看 | 国产视频1区2区 | 日韩精品在线一区 | 久久久久久国产精品 | 久久综合成人精品亚洲另类欧美 | 成人在线一区二区三区 | 日韩高清三区 | 欧美精品区 | 一区二区三区四区视频 | 欧美αv | 午夜午夜精品一区二区三区文 | 黄色永久免费 | 国产成人综合在线 | 亚洲精品三级 | 日韩成人精品一区二区三区 | 久久久成人一区二区免费影院 | 亚洲成人国产 | 精品成人av| 成年人网站免费视频 | 午夜精品 | 青青草一区二区三区 | 久久国产美女视频 |