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

  1. <small id='cKzae'></small><noframes id='cKzae'>

  2. <legend id='cKzae'><style id='cKzae'><dir id='cKzae'><q id='cKzae'></q></dir></style></legend>

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

      <tfoot id='cKzae'></tfoot>
    1. 重載運算符<<對于模板類

      Overloading operatorlt;lt; for a templated class(重載運算符對于模板類)
    2. <i id='l1QvQ'><tr id='l1QvQ'><dt id='l1QvQ'><q id='l1QvQ'><span id='l1QvQ'><b id='l1QvQ'><form id='l1QvQ'><ins id='l1QvQ'></ins><ul id='l1QvQ'></ul><sub id='l1QvQ'></sub></form><legend id='l1QvQ'></legend><bdo id='l1QvQ'><pre id='l1QvQ'><center id='l1QvQ'></center></pre></bdo></b><th id='l1QvQ'></th></span></q></dt></tr></i><div class="bl7bztz" id='l1QvQ'><tfoot id='l1QvQ'></tfoot><dl id='l1QvQ'><fieldset id='l1QvQ'></fieldset></dl></div>

          <tbody id='l1QvQ'></tbody>
          <bdo id='l1QvQ'></bdo><ul id='l1QvQ'></ul>

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

          <legend id='l1QvQ'><style id='l1QvQ'><dir id='l1QvQ'><q id='l1QvQ'></q></dir></style></legend>

                <tfoot id='l1QvQ'></tfoot>
                本文介紹了重載運算符<<對于模板類的處理方法,對大家解決問題具有一定的參考價值,需要的朋友們下面隨著小編來一起學習吧!

                問題描述

                限時送ChatGPT賬號..

                我正在嘗試為返回流的二叉樹實現一種方法.我想使用方法中返回的流在屏幕中顯示樹或將樹保存在文件中:

                I'm trying to implement a method for a binary tree which returns a stream. I want to use the stream returned in a method to show the tree in the screen or to save the tree in a file:

                這兩個方法都在二叉樹的類中:

                These two methods are in the class of the binary tree:

                聲明:

                void streamIND(ostream&,const BinaryTree<T>*);
                friend ostream& operator<<(ostream&,const BinaryTree<T>&);
                
                template <class T>
                ostream& operator<<(ostream& os,const BinaryTree<T>& tree) {
                    streamIND(os,tree.root);
                    return os;
                }
                
                template <class T>
                void streamIND(ostream& os,Node<T> *nb) {
                    if (!nb) return;
                    if (nb->getLeft()) streamIND(nb->getLeft());
                    os << nb->getValue() << " ";
                    if (nb->getRight()) streamIND(nb->getRight());
                }
                

                該方法在 UsingTree 類中:

                This method is in UsingTree class:

                void UsingTree::saveToFile(char* file = "table") {
                    ofstream f;
                    f.open(file,ios::out);
                    f << tree;
                    f.close();
                }
                

                所以我重載了運算符<<"要使用的 BinaryTree 類: cout <<樹和ofstream f<<樹,但我收到下一條錯誤消息: undefined reference to `operator<<(std::basic_ostream >&, BinaryTree&)'

                So I overloaded the operator "<<" of the BinaryTree class to use: cout << tree and ofstream f << tree, but I receive the next error message: undefined reference to `operator<<(std::basic_ostream >&, BinaryTree&)'

                附言該樹存儲 Word 對象(帶有 int 的字符串).

                P.S. The tree stores Word objects (a string with an int).

                我希望你能理解我糟糕的英語.謝謝!我想知道一篇關于 STL 初學者的好文章,它解釋了所有必要的內容,因為我把所有的時間都浪費在這樣的錯誤上.

                I hope you understand my poor English. Thank you! And I'd like to know a good text for beginners about STL which explains all necessary because i waste all my time in errors like this.

                saveToFile() 中的樹聲明為:BinaryTree<詞 > 樹.

                tree in saveToFile() is declared: BinaryTree< Word > tree.

                推薦答案

                問題是編譯器沒有嘗試使用您提供的模板化operator<<,而是一個非模板化的版本.

                The problem is that the compiler is not trying to use the templated operator<< you provided, but rather a non-templated version.

                當您在類中聲明友元時,您就是在封閉作用域中注入了該函數的聲明.以下代碼的作用是聲明(而不是定義)一個自由函數,該函數通過常量引用接受 non_template_test 參數:

                When you declare a friend inside a class you are injecting the declaration of that function in the enclosing scope. The following code has the effect of declaring (and not defining) a free function that takes a non_template_test argument by constant reference:

                class non_template_test
                {
                   friend void f( non_template_test const & );
                };
                // declares here:
                // void f( non_template_test const & ); 
                

                模板類也會發生同樣的情況,即使在這種情況下它不那么直觀.當您在模板類主體中聲明(而不是定義)友元函數時,您是在聲明一個具有該確切參數的自由函數.請注意,您聲明的是一個函數,而不是一個模板函數:

                The same happens with template classes, even if in this case it is a little less intuitive. When you declare (and not define) a friend function within the template class body, you are declaring a free function with that exact arguments. Note that you are declaring a function, not a template function:

                template<typename T>
                class template_test
                {
                    friend void f( template_test<T> const & t );
                };
                // for each instantiating type T (int, double...) declares:
                // void f( template_test<int> const & );
                // void f( template_test<double> const & );
                
                int main() {
                    template_test<int> t1;
                    template_test<double> t2;
                }
                

                那些自由函數已聲明但未定義.這里的棘手部分是那些自由函數不是模板,而是被聲明的常規自由函數.當您將模板函數添加到組合中時,您會得到:

                Those free functions are declared but not defined. The tricky part here is that those free functions are not a template, but regular free functions being declared. When you add the template function into the mix you get:

                template<typename T> class template_test {
                   friend void f( template_test<T> const & );
                };
                // when instantiated with int, implicitly declares:
                // void f( template_test<int> const & );
                
                template <typename T>
                void f( template_test<T> const & x ) {} // 1
                
                int main() {
                   template_test<int> t1;
                   f( t1 );
                }
                

                當編譯器遇到 main 函數時,它會實例化模板 template_test 類型為 int 并聲明自由函數 void f( template_test const &; ) 不是模板化的.當它找到調用 f( t1 ) 時,有兩個 f 符號匹配:非模板 f( template_test const & )template_test 實例化時聲明(但未定義),并且模板化版本在 1 處聲明和定義.非模板版本優先,編譯器匹配.

                When the compiler hits the main function it instantiates the template template_test with type int and that declares the free function void f( template_test<int> const & ) that is not templated. When it finds the call f( t1 ) there are two f symbols that match: the non-template f( template_test<int> const & ) declared (and not defined) when template_test was instantiated and the templated version that is both declared and defined at 1. The non-templated version takes precedence and the compiler matches it.

                當鏈接器嘗試解析 f 的非模板版本時,它找不到符號,因此失敗.

                When the linker tries to resolve the non-templated version of f it cannot find the symbol and it thus fails.

                我們能做什么?有兩種不同的解決方案.在第一種情況下,我們讓編譯器為每個實例化類型提供非模板化函數.在第二種情況下,我們將模板化版本聲明為朋友.它們略有不同,但在大多數情況下是相同的.

                What can we do? There are two different solutions. In the first case we make the compiler provide non-templated functions for each instantiating type. In the second case we declare the templated version as a friend. They are subtly different, but in most cases equivalent.

                讓編譯器為我們生成非模板化函數:

                template <typename T>
                class test 
                {
                   friend void f( test<T> const & ) {}
                };
                // implicitly
                

                這具有根據需要創建盡可能多的非模板化自由函數的效果.當編譯器在模板 test 中找到友元聲明時,它不僅會找到聲明,還會找到實現并將兩者都添加到封閉作用域中.

                This has the effect of creating as many non-templated free functions as needed. When the compiler finds the friend declaration within the template test it not only finds the declaration but also the implementation and adds both to the enclosing scope.

                讓模板化版本成為朋友

                要使模板成為朋友,我們必須已經聲明它并告訴編譯器我們想要的朋友實際上是模板而不是非模板化的自由函數:

                To make the template a friend we must have it already declared and tell the compiler that the friend we want is actually a template and not a non-templated free function:

                template <typename T> class test; // forward declare the template class
                template <typename T> void f( test<T> const& ); // forward declare the template
                template <typename T>
                class test {
                   friend void f<>( test<T> const& ); // declare f<T>( test<T> const &) a friend
                };
                template <typename T> 
                void f( test<T> const & ) {}
                

                在這種情況下,在將 f 聲明為模板之前,我們必須先聲明模板.要聲明 f 模板,我們必須先向前聲明 test 模板.友元聲明被修改為包含尖括號,用于標識我們要成為友元的元素實際上是一個模板而不是一個自由函數.

                In this case, prior to declaring f as a template we must forward declare the template. To declare the f template we must first forward declare the test template. The friend declaration is modified to include the angle brackets that identify that the element we are making a friend is actually a template and not a free function.

                回到問題

                回到您的特定示例,最簡單的解決方案是讓編譯器通過內聯友元函數的聲明為您生成函數:

                Going back to your particular example, the simplest solution is having the compiler generate the functions for you by inlining the declaration of the friend function:

                template <typename T>
                class BinaryTree {
                   friend std::ostream& operator<<( std::ostream& o, BinaryTree const & t ) {
                      t.dump(o);
                      return o;
                   }
                   void dump( std::ostream& o ) const;
                };
                

                使用該代碼,您將迫使編譯器為每個實例化類型生成一個非模板化的 operator<<,并在 dump 方法上生成函數委托模板.

                With that code you are forcing the compiler into generating a non-templated operator<< for each instantiated type, and that generated function delegates on the dump method of the template.

                這篇關于重載運算符<<對于模板類的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持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 不能)

                  <tbody id='jmZiv'></tbody>
                  • <small id='jmZiv'></small><noframes id='jmZiv'>

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

                          主站蜘蛛池模板: 越南专线物流_东莞国际物流_东南亚专线物流_行通物流 | 智能门锁电机_智能门锁离合器_智能门锁电机厂家-温州劲力智能科技有限公司 | 钢格板|镀锌钢格板|热镀锌钢格板|格栅板|钢格板|钢格栅板|热浸锌钢格板|平台钢格板|镀锌钢格栅板|热镀锌钢格栅板|平台钢格栅板|不锈钢钢格栅板 - 专业钢格板厂家 | 100_150_200_250_300_350_400公斤压力空气压缩机-舰艇航天配套厂家 | 哈希PC1R1A,哈希CA9300,哈希SC4500-上海鑫嵩实业有限公司 | 阳光1号桔柚_无核沃柑_柑橘新品种枝条苗木批发 - 苧金网 | 机械立体车库租赁_立体停车设备出租_智能停车场厂家_春华起重 | 实验室pH计|电导率仪|溶解氧测定仪|离子浓度计|多参数水质分析仪|pH电极-上海般特仪器有限公司 | 美缝剂_美缝剂厂家_美缝剂加盟-地老板高端瓷砖美缝剂 | 药品/药物稳定性试验考察箱-埃里森仪器设备(上海)有限公司 | 合景一建-无尘车间设计施工_食品医药洁净车间工程装修总承包公司 | 上海佳武自动化科技有限公司 | 华溶溶出仪-Memmert稳定箱-上海协烁仪器科技有限公司 | 澳威全屋定制官网|极简衣柜十大品牌|衣柜加盟代理|全屋定制招商 百度爱采购运营研究社社群-店铺托管-爱采购代运营-良言多米网络公司 | 工业雾炮机_超细雾炮_远程抑尘射雾器-世纪润德环保设备 | 洁净棚-洁净工作棚-无菌室-净化工程公司_北京卫护科技有限公司 | 粒米特测控技术(上海)有限公司-测功机_减速机测试台_电机测试台 | 分子精馏/精馏设备生产厂家-分子蒸馏工艺实验-新诺舜尧(天津)化工设备有限公司 | 今日娱乐圈——影视剧集_八卦娱乐_明星八卦_最新娱乐八卦新闻 | 专业的新乡振动筛厂家-振动筛品质保障-环保振动筛价格—新乡市德科筛分机械有限公司 | 科客,主见不成见| 钢结构-钢结构厂房-钢结构工程[江苏海逵钢构厂] | 并离网逆变器_高频UPS电源定制_户用储能光伏逆变器厂家-深圳市索克新能源 | 众能联合-提供高空车_升降机_吊车_挖机等一站工程设备租赁 | 薪动-人力资源公司-灵活用工薪资代发-费用结算-残保金优化-北京秒付科技有限公司 | 挤奶设备过滤纸,牛奶过滤纸,挤奶机过滤袋-济南蓝贝尔工贸有限公司 | 长沙网站建设制作「网站优化推广」-网页设计公司-速马科技官网 | 浙江筋膜枪-按摩仪厂家-制造商-肩颈按摩仪哪家好-温州市合喜电子科技有限公司 | 超细|超微气流粉碎机|气流磨|气流分级机|粉体改性机|磨粉机|粉碎设备-山东埃尔派粉体科技 | 南京种植牙医院【官方挂号】_南京治疗种植牙医院那个好_南京看种植牙哪里好_南京茀莱堡口腔医院 尼龙PA610树脂,尼龙PA612树脂,尼龙PA1010树脂,透明尼龙-谷骐科技【官网】 | 辽宁资质代办_辽宁建筑资质办理_辽宁建筑资质延期升级_辽宁中杭资质代办 | 厚壁钢管-厚壁无缝钢管-小口径厚壁钢管-大口径厚壁钢管 - 聊城宽达钢管有限公司 | 挤奶设备过滤纸,牛奶过滤纸,挤奶机过滤袋-济南蓝贝尔工贸有限公司 | 工业车间焊接-整体|集中除尘设备-激光|等离子切割机配套除尘-粉尘烟尘净化治理厂家-山东美蓝环保科技有限公司 | 杭州月嫂技术培训服务公司-催乳师培训中心报名费用-产后康复师培训机构-杭州优贝姆健康管理有限公司 | 干洗店加盟_洗衣店加盟_干洗店设备-伊蔻干洗「武汉总部」 | 工业机械三维动画制作 环保设备原理三维演示动画 自动化装配产线三维动画制作公司-南京燃动数字 聚合氯化铝_喷雾聚氯化铝_聚合氯化铝铁厂家_郑州亿升化工有限公司 | 热工多功能信号校验仪-热电阻热电偶校验仿真仪-金湖虹润仪表 | 中央空调温控器_风机盘管温控器_智能_液晶_三速开关面板-中央空调温控器厂家 | Copeland/谷轮压缩机,谷轮半封闭压缩机,谷轮涡旋压缩机,型号规格,技术参数,尺寸图片,价格经销商 CTP磁天平|小电容测量仪|阴阳极极化_双液系沸点测定仪|dsj电渗实验装置-南京桑力电子设备厂 | 圣才学习网-考研考证学习平台,提供万种考研考证电子书、题库、视频课程等考试资料 |