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

  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="qwawimqqmiuu" 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="qwawimqqmiuu" 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="qwawimqqmiuu" 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>

                          主站蜘蛛池模板: 九九综合九九 | 中文字幕视频免费 | 欧美多人在线 | 免费av在线 | a黄视频 | 一级片在线观看 | av中文字幕在线观看 | 精品中文字幕视频 | 欧美一区二区视频 | 精品久久国产 | 日韩一级黄色毛片 | 中文字幕在线三区 | 日本成人在线网址 | 欧美综合视频在线 | 在线视频 中文字幕 | 婷婷狠狠 | 黄色av一区 | 精品三区| 色婷婷综合久久久中字幕精品久久 | 国产一级电影在线 | 欧美一级免费看 | 一级黄色网页 | 黑人中文字幕一区二区三区 | 欧美色综合 | 日韩在线观看中文字幕 | 综合精品在线 | 午夜精品久久久久久久久久久久久 | 亚洲人人| 欧美黄页| 欧美xxxⅹ性欧美大片 | 国产中文字幕在线观看 | 久久精品一区二区三区四区 | 综合二区 | 国产一级在线观看 | av天天爽 | av一区二区在线观看 | 欧美毛片免费观看 | 99久久精品国产一区二区三区 | 丝袜 亚洲 欧美 日韩 综合 | 亚洲一区二区三区在线播放 | 日韩欧美在线视频 |