pbootcms网站模板|日韩1区2区|织梦模板||网站源码|日韩1区2区|jquery建站特效-html5模板网

  • <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="hd5jx7f" 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="nrzj7ft" 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++ 模板很有趣]的處理方法,對大家解決問題具有一定的參考價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧!

                  問題描述

                  限時送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
                  

                  所以我的問題是代碼示例格式錯誤嗎?"據(jù)我說是".這是否意味著這是 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 認(rèn)為他們是對的

                  K,即注入的類名,在K的范圍內(nèi)具有雙重性質(zhì).您可以在沒有模板參數(shù)的情況下使用它.然后它引用 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).

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

                  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.

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

                  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.

                  標(biāo)準(zhǔn)有一個這樣的例子:

                  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
                  };
                  

                  人們可能傾向于由此得出結(jié)論,目的是您可以放棄模板.標(biāo)準(zhǔn)說

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

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

                  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 中查找模板自己的范圍(它被稱為當(dāng)前實例化"),你可以正式放棄 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.

                  為了讓它更復(fù)雜,我們將不得不考慮 K 的構(gòu)造函數(shù).隱式聲明了一個默認(rèn)構(gòu)造函數(shù)和一個復(fù)制構(gòu)造函數(shù).名稱 K::K 將引用 K 的構(gòu)造函數(shù) 除非 使用的名稱查找將忽略函數(shù)(構(gòu)造函數(shù))名稱.typename T::K 會忽略函數(shù)名嗎?3.4.4/3 說明了詳細(xì)的類型說明符,其中 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,則根據(jù)其限定條件查找名稱,如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 中指定的構(gòu)造函數(shù)(僅在 not 忽略非類型時才會發(fā)生的附加扭曲是由后來的缺陷報告添加的,所有流行的 C++03 編譯器雖然實現(xiàn)):

                  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 的構(gòu)造函數(shù).這樣的構(gòu)造函數(shù)名稱只能在出現(xiàn)在類定義之外的構(gòu)造函數(shù)定義的聲明符中使用.

                  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.

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

                  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).

                  讓我們通過派生類訪問注入的名稱來更改它,這樣就不會發(fā)生構(gòu)造函數(shù)名稱轉(zhuǎn)換,并且您真的訪問了類型,以便您真的 可以附加模板參數(shù):

                  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;
                  };
                  

                  現(xiàn)在所有東西都可以用 comeau 編譯了!請注意,我已經(jīng)向 clang 做了關(guān)于這件事的問題報告.請參閱錯誤的構(gòu)造函數(shù)名稱解析.順便說一句,如果你在 K 中聲明了一個默認(rèn)構(gòu)造函數(shù),如果你使用 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;
                  

                  這篇關(guān)于g++/Clang 中的另一個錯誤?[C++ 模板很有趣]的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網(wǎng)!

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

                  相關(guān)文檔推薦

                  Why do two functions have the same address?(為什么兩個函數(shù)的地址相同?)
                  Why the initializer of std::function has to be CopyConstructible?(為什么 std::function 的初始化程序必須是可復(fù)制構(gòu)造的?)
                  mixing templates with polymorphism(混合模板與多態(tài)性)
                  When should I use the keyword quot;typenamequot; when using templates(我什么時候應(yīng)該使用關(guān)鍵字“typename?使用模板時)
                  Dependent name resolution amp; namespace std / Standard Library(依賴名稱解析命名空間 std/標(biāo)準(zhǔn)庫)
                  gcc can compile a variadic template while clang cannot(gcc 可以編譯可變參數(shù)模板,而 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="txnln7p" 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>

                            主站蜘蛛池模板: 青岛球场围网,青岛车间隔离网,青岛机器人围栏,青岛水源地围网,青岛围网,青岛隔离栅-青岛晟腾金属制品有限公司 | 起好名字_取个好名字_好名网免费取好名在线打分 | 深圳办公室装修-写字楼装修设计-深圳标榜装饰公司 | 工业洗衣机_工业洗涤设备_上海力净工业洗衣机厂家-洗涤设备首页 bkzzy在职研究生网 - 在职研究生招生信息咨询平台 | 截齿|煤截齿|采煤机截齿|掘进机截齿|旋挖截齿-山东卓力截齿厂家报价 | 全自动过滤器_反冲洗过滤器_自清洗过滤器_量子除垢环_量子环除垢_量子除垢 - 安士睿(北京)过滤设备有限公司 | 大通天成企业资质代办_承装修试电力设施许可证_增值电信业务经营许可证_无人机运营合格证_广播电视节目制作许可证 | 自动部分收集器,进口无油隔膜真空泵,SPME固相微萃取头-上海楚定分析仪器有限公司 | 水上浮桥-游艇码头-浮动码头-游船码头-码瑞纳游艇码头工程 | 定制奶茶纸杯_定制豆浆杯_广东纸杯厂_[绿保佳]一家专业生产纸杯碗的厂家 | 北京网络营销推广_百度SEO搜索引擎优化公司_网站排名优化_谷歌SEO - 北京卓立海创信息技术有限公司 | 扫地车厂家-山西洗地机-太原电动扫地车「大同朔州吕梁晋中忻州长治晋城洗地机」山西锦力环保科技有限公司 | 包塑丝_高铁绑丝_地暖绑丝_涂塑丝_塑料皮铁丝_河北创筹金属丝网制品有限公司 | 渣油泵,KCB齿轮泵,不锈钢齿轮泵,重油泵,煤焦油泵,泊头市泰邦泵阀制造有限公司 | 搅拌磨|搅拌球磨机|循环磨|循环球磨机-无锡市少宏粉体科技有限公司 | 【电子厂招聘_普工招工网_工厂招聘信息平台】-工立方打工网 | 清水-铝合金-建筑模板厂家-木模板价格-铝模板生产「五棵松」品牌 | 赛尔特智能移动阳光房-阳光房厂家-赛尔特建筑科技(广东)有限公司 | 高压管道冲洗清洗机_液压剪叉式升降机平台厂家-林君机电 | UV固化机_UVLED光固化机_UV干燥机生产厂家-上海冠顶公司专业生产UV固化机设备 | 青岛成人高考_山东成考报名网 | 上海刑事律师|刑事辩护律师|专业刑事犯罪辩护律师免费咨询-[尤辰荣]金牌上海刑事律师团队 | 聚合氯化铝_喷雾聚氯化铝_聚合氯化铝铁厂家_郑州亿升化工有限公司 | 分子精馏/精馏设备生产厂家-分子蒸馏工艺实验-新诺舜尧(天津)化工设备有限公司 | 双齿辊破碎机-大型狼牙破碎机视频-对辊破碎机价格/型号图片-金联机械设备生产厂家 | 苏州工作服定做-工作服定制-工作服厂家网站-尺品服饰科技(苏州)有限公司 | 招商帮-一站式网络营销服务|搜索营销推广|信息流推广|短视视频营销推广|互联网整合营销|网络推广代运营|招商帮企业招商好帮手 | PSI渗透压仪,TPS酸度计,美国CHAI PCR仪,渗透压仪厂家_价格,微生物快速检测仪-华泰和合(北京)商贸有限公司 | 深圳富泰鑫五金_五金冲压件加工_五金配件加工_精密零件加工厂 | 超声波清洗机_大型超声波清洗机_工业超声波清洗设备-洁盟清洗设备 | 网站建设-高端品牌网站设计制作一站式定制_杭州APP/微信小程序开发运营-鼎易科技 | 液压中心架,数控中心架,自定心中心架-烟台恒阳机电设计有限公司 行星搅拌机,双行星搅拌机,动力混合机,无锡米克斯行星搅拌机生产厂家 | 聚丙烯酰胺_厂家_价格-河南唐达净水材料有限公司 | 石家庄网站建设|石家庄网站制作|石家庄小程序开发|石家庄微信开发|网站建设公司|网站制作公司|微信小程序开发|手机APP开发|软件开发 | 沈阳激光机-沈阳喷码机-沈阳光纤激光打标机-沈阳co2激光打标机 | 液压油缸-液压缸厂家价格,液压站系统-山东国立液压制造有限公司 液压油缸生产厂家-山东液压站-济南捷兴液压机电设备有限公司 | [品牌官网]贵州遵义双宁口腔连锁_贵州遵义牙科医院哪家好_种植牙_牙齿矫正_原华美口腔 | 办公室家具公司_办公家具品牌厂家_森拉堡办公家具【官网】 | 美的商用净水器_美的直饮机_一级代理经销商_Midea租赁价格-厂家反渗透滤芯-直饮水批发品牌售后 | 溶氧传感器-pH传感器|哈美顿(hamilton) | 西安耀程造价培训机构_工程预算实训_广联达实作实操培训 |