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

  • <tfoot id='JesKc'></tfoot>

      • <bdo id='JesKc'></bdo><ul id='JesKc'></ul>
      <legend id='JesKc'><style id='JesKc'><dir id='JesKc'><q id='JesKc'></q></dir></style></legend>

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

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

        g++/Clang 中的另一個錯誤?[C++ 模板很有趣]

        Another bug in g++/Clang? [C++ Templates are fun](g++/Clang 中的另一個錯誤?[C++ 模板很有趣])
            <bdo id='t1g15'></bdo><ul id='t1g15'></ul>
            <tfoot id='t1g15'></tfoot>

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

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

                  <tbody id='t1g15'></tbody>
                <legend id='t1g15'><style id='t1g15'><dir id='t1g15'><q id='t1g15'></q></dir></style></legend>
                • 本文介紹了g++/Clang 中的另一個錯誤?[C++ 模板很有趣]的處理方法,對大家解決問題具有一定的參考價值,需要的朋友們下面隨著小編來一起學習吧!

                  問題描述

                  限時送ChatGPT賬號..

                  看看下面的代碼(只是為了好玩)

                  Check out the following code (written just for fun)

                  namespace N
                  {
                     template<typename T>
                     struct K
                     {
                  
                     };
                  }
                  template<typename T>
                  struct X
                  {
                     typename T::template K<T> *p; //should give error 
                                                   //N::K<int> has no template member named `K`
                  };
                  
                  int main()
                  {
                     X<N::K<int> > l;
                  }
                  

                  代碼在 g++(4.5.1) 和 Clang 上編譯,而 Comeau 和 Intel C++ 給出(類似)錯誤.

                  The code gets compiled on g++(4.5.1) and Clang whereas Comeau and Intel C++ give (similar) errors.

                  我在 Comeau 上遇到的錯誤是:

                  The errors that I get on Comeau are :

                  "ComeauTest.c", line 13: error: class "N::K<int>" has no member "K"
                       typename T::template K<T> *p;
                                            ^
                            detected during instantiation of class "X<T> [with T=N::K<int>]" at
                                      line 18
                  
                  "ComeauTest.c", line 13: error: expected an identifier
                       typename T::template K<T> *p;
                                             ^
                            detected during instantiation of class "X<T> [with T=N::K<int>]" at
                                      line 18
                  

                  所以我的問題是代碼示例格式錯誤嗎?"據我說是".這是否意味著這是 g++/Clang 中的另一個錯誤?

                  So my question is "Is the code sample ill-formed ?" According to me "Yes". Does that mean this is yet another bug in g++/Clang?

                  推薦答案

                  為什么 GCC 和 Clang 認為他們是對的

                  K,即注入的類名,在K的范圍內具有雙重性質.您可以在沒有模板參數的情況下使用它.然后它引用 K(指向它自己的類型).

                  Why GCC and Clang think they are right

                  K, which is the injected class name, has a dual nature in the scope of K<int>. You can use it without template arguments. Then it refers to K<int> (to its own type).

                  它后面也可以跟一個模板參數列表.IMO 可以合理地說您需要使用 template 作為前綴,因為解析器與后面的 < 有歧義.然后它引用由模板參數確定的指定類型.

                  It can be followed by a template argument list too. IMO it's reasonable to say that you need to prefix it with template because of the parser ambiguity with the < that follows. It then refers to the specified type that's determined by the template arguments.

                  因此可以將其視為成員模板和嵌套類型,具體取決于它后面是否跟有模板參數列表.當然,K 并不是真正的成員模板.盡管如此,注入的類名的雙重性質在我看來更像是一種黑客攻擊.

                  So it can be treated as a member template and as a nested type, depending on whether it's followed by a template argument list. Of course, K is not really a member template. The dual nature of the injected class name seems to me more of a hack anyway, though.

                  標準有一個這樣的例子:

                  The Standard has an example that reads like this:

                  template <class T> struct Base { };
                  template <class T> struct Derived: Base<int>, Base<char> {
                     typename Derived::Base b; // error: ambiguous
                     typename Derived::Base<double> d; // OK
                  };
                  

                  人們可能傾向于由此得出結論,目的是您可以放棄模板.標準說

                  One might be inclined to conclude from this that the intent is that you could leave off the template. The Standard says

                  對于要由模板參數顯式限定的模板名稱,必須知道該名稱以引用模板.

                  For a template-name to be explicitly qualified by the template arguments, the name must be known to refer to a template.

                  我看不出這如何不適用于 T::K.如果 T 是一個依賴類型,那么你可以向后靠,因為在解析它時你不知道 K 指的是什么,所以為了理解代碼,你只需要能夠以 template 為前綴.請注意,n3225 也有這個例子,但它不是一個缺陷:如果你在 C++0x 中查找模板自己的范圍(它被稱為當前實例化"),你可以正式放棄 template.

                  I can't see how this wouldn't apply to T::K<T>. If T is a dependent type then you can just lean back because you can't know what K refers to when parsing it, so to make any sense of the code, you just have to be able to prefix it with template. Notice that n3225 has that example too, but it's not a defect there: You can officially leave off template if you lookup into the template's own scope in C++0x (it's called the "current instantiation").

                  所以到目前為止,Clang 和 GCC 都很好.

                  So until now, Clang and GCC are fine.

                  為了讓它更復雜,我們將不得不考慮 K 的構造函數.隱式聲明了一個默認構造函數和一個復制構造函數.名稱 K::K 將引用 K 的構造函數 除非 使用的名稱查找將忽略函數(構造函數)名稱.typename T::K 會忽略函數名嗎?3.4.4/3 說明了詳細的類型說明符,其中 typename ... 是其中之一:

                  Just to make it even more complicated, we will have to consider the constructors of K<int>. There is a default constructor and a copy constructor implicitly declared. A name K<int>::K will refer to the constructor(s) of K<int> unless the name lookup used will ignore function (constructor) names. Will typename T::K ignore function names? 3.4.4/3 says about elaborated type specifiers, which typename ... is one of:

                  如果名稱是qualified-id,則根據其限定條件查找名稱,如3.4.3 所述,但忽略任何已聲明的非類型名稱.

                  If the name is a qualified-id, the name is looked up according its qualifications, as described in 3.4.3, but ignoring any non-type names that have been declared.

                  然而,typename ... 使用不同的查找.14.6/4 說

                  However, a typename ... uses different lookup. 14.6/4 says

                  通常的限定名稱查找 (3.4.3) 用于查找限定 ID,即使存在 typename 也是如此.

                  The usual qualified name lookup (3.4.3) is used to find the qualified-id even in the presence of typename.

                  3.4.3 的通常限定查找不會忽略非類型名稱,如 14.6/4 所附示例所示.因此,我們將找到 3.4.3.1/1a 中指定的構造函數(僅在 not 忽略非類型時才會發生的附加扭曲是由后來的缺陷報告添加的,所有流行的 C++03 編譯器雖然實現):

                  The usual qualified lookup of 3.4.3 won't ignore non-type names, as illustrated by the example attached to 14.6/4. So, we will find the constructor(s) as specified by 3.4.3.1/1a (the additional twist that this only happens when non-types are not ignored was added by a later defect report, which all popular C++03 compilers implement though):

                  如果嵌套名稱說明符指定一個類 C,并且在嵌套名稱說明符后面指定的名稱在 C 中查找時是 C 的注入類名稱(第 9 條),則名稱為而是考慮命名類 C 的構造函數.這樣的構造函數名稱只能在出現在類定義之外的構造函數定義的聲明符中使用.

                  If the nested-name-specifier nominates a class C, and the name specified after the nested-name-specifier, when looked up in C, is the injected-class-name of C (clause 9), the name is instead considered to name the constructor of class C. Such a constructor name shall be used only in the declarator-id of a constructor definition that appears outside of the class definition.

                  所以最后,我認為 comeau 的診斷是正確的,因為您嘗試將模板參數列表放在非模板上,并且還違反了最后一部分中引用的要求(您在其他地方使用了該名稱).

                  So in the end, I think comeau is correct to diagnose this, because you try to put a template argument list onto a non-template and also violate the requirement quoted in the last part (you use the name elsewhere).

                  讓我們通過派生類訪問注入的名稱來更改它,這樣就不會發生構造函數名稱轉換,并且您真的訪問了類型,以便您真的 可以附加模板參數:

                  Let's change it by accessing the injected name by a derived class, so no constructor name translation occurs, and you really access the type so that you really can append the template arguments:

                  // just replace struct X with this:
                  template<typename T>
                  struct X
                  {
                     struct Derived : T { };
                     typename Derived::template K<T> *p;
                  };
                  

                  現在所有東西都可以用 comeau 編譯了!請注意,我已經向 clang 做了關于這件事的問題報告.請參閱錯誤的構造函數名稱解析.順便說一句,如果你在 K 中聲明了一個默認構造函數,如果你使用 T::K

                  Everything compiles now with comeau too! Notice I already did problem report to clang about this exact thing. See Incorrect constructor name resolution. BTW, if you declare a default constructor in K, you can see comeau give a better error message if you use T::K<int>

                  "ComeauTest.c", line 13: error: overloaded function "N::K<T>::K [with T=int]" is
                            not a template
                       typename T::template K<T> *p;
                  

                  這篇關于g++/Clang 中的另一個錯誤?[C++ 模板很有趣]的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持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 不能)

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

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

                        <tbody id='YbGDq'></tbody>
                      <tfoot id='YbGDq'></tfoot>
                        • <legend id='YbGDq'><style id='YbGDq'><dir id='YbGDq'><q id='YbGDq'></q></dir></style></legend>

                            主站蜘蛛池模板: 欧美九九九| 97国产精品 | 久视频在线 | 午夜免费观看视频 | 一区二区三区四区精品 | 国产在线毛片 | 二区三区在线观看 | 香蕉视频免费 | 成人短视频在线观看 | 欧美一级淫片bbb一84 | 久久精品国产一区二区 | 欧美国产精品 | 黄色av免费| 国产精品永久久久久久久久久 | av网站网址 | 99热99re6国产在线播放 | 麻豆av免费| 中文在线观看免费高清 | 久久久美女 | 国产精品久久久久久久久久久久久久久 | 国产精品黄色片 | 一级片在线 | 欧美日韩毛片 | 99精品国产一区二区 | 色综合99| 天天干天天曰 | 日韩欧美一级 | 日本成人小视频 | 日韩中文视频 | 中文字幕www| 中文字幕在线免费播放 | 日韩欧美国产成人 | 免费三级网站 | 91新视频| 成人一级片 | www性 | 日韩欧美一级 | 久久国产小视频 | 国内精品一区二区三区 | 福利视频网站 | 香蕉久久久 |