• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            posts - 9, comments - 0, trackbacks - 0, articles - 0
              C++博客 :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

            類模板中的友元函數

            Posted on 2013-01-21 10:48 魏尚堂 閱讀(594) 評論(0)  編輯 收藏 引用
            template <typename T> class dataList
            {
               public:
                  friend ostream& operator<<(ostream& outStream, const dataList <T> &outList);
            }
            template <typename T> ostream& operator<<(ostream& outStream, const dataList <T> &outList)
            {
               //....
               return outStream;
            }
            int main(int argc, char* argv[])
            {
               dataList <int> testList;
               cout << testList;
            }
            這個程序員是鏈接不過,
            錯誤信息:
             warning: friend declaration âstd::ostream& operator<<(std::ostream&, const dataList<T>&)â declares a non-template function
             note: (if this is not what you intended, make sure the function template has already been declared and add <> after the function name here)
            /tmp/cc9DSuka.o: In function `main':
            undefined reference to `operator<<(std::basic_ostream<char, std::char_traits<char> >&, dataList<int> const&)'
            collect2: ld returned 1 exit status
            錯誤原因解釋

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

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

            When the compiler hits the main function it instantiates the template template_test with type intand 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.

            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.

            Having the compiler generate the non-templated functions for us:

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

            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.

            Making the templated version a friend

            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 & ) {}

            In this case, prior to declaring f as a template we must forward declare the template. To declare the ftemplate 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.
            引用自 http://stackoverflow.com/questions/1810753/overloading-operator-for-a-templated-class
            從上面我可以學到一點:
            1, 編譯器匹配方法時非模板函數優先模板函數
            2, 友元函數模板必須提前聲明

            国内精品久久国产| 久久久久人妻精品一区二区三区| 久久人人爽人人澡人人高潮AV| 久久久青草青青国产亚洲免观| 久久亚洲精品国产精品婷婷| 性做久久久久久久| 蜜桃麻豆www久久国产精品| 精品久久久无码人妻中文字幕| 国产99精品久久| 狠狠色丁香久久婷婷综合_中| 99久久国产热无码精品免费 | 热久久最新网站获取| 亚洲午夜久久久影院| 久久久WWW成人免费毛片| 久久精品国产亚洲AV无码娇色| 欧美日韩中文字幕久久久不卡| 国产成人精品白浆久久69| 久久亚洲中文字幕精品一区| 国产精品成人久久久久久久| 久久国产色AV免费观看| 中文字幕乱码人妻无码久久| 日韩久久久久中文字幕人妻 | 97精品国产97久久久久久免费| 精品水蜜桃久久久久久久| 日本久久久久久中文字幕| 久久婷婷五月综合97色一本一本| 久久这里只精品99re66| 亚洲国产成人精品久久久国产成人一区二区三区综 | 久久久久亚洲av成人无码电影| 久久精品9988| 99久久99久久精品国产片果冻| 国产精品福利一区二区久久| 精品久久久噜噜噜久久久 | 久久国产精品成人片免费| 亚洲va国产va天堂va久久| 亚洲熟妇无码另类久久久| 亚洲国产欧洲综合997久久| 色欲综合久久躁天天躁蜜桃| 无码国产69精品久久久久网站| 欧美伊人久久大香线蕉综合| 99精品国产99久久久久久97|