Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.1k views
in Technique[技术] by (71.8m points)

visual studio 2010 - C++ template friend function not linking

I have the following code which compiles in VC6 :

Text.h:

template <typename T>
class CTextT
{
   public:

    friend  CTextT add(const CTextT& text1, const CTextT& text2) ;

friend CTextT operator+(const CTextT& string1, const CTextT& string2)   
    {  
       return ::add(string1, string2);}
    }

    ....................
};

And at the end of the header

 #include "Text.inl"

Text.inl:

template <typename T>
CTextT<T> add(const CTextT<T>& text1, const CTextT<T>& text2) 
{   
    CTextT<T> temp ;

    // do something

    return temp ;
}

But VC2010 gives me LINK error:

error LNK2019: unresolved external symbol "class CTextT<char> __cdecl add(class     CTextT<char> const &,class CTextT<char> const &)" (?add@@YA?AV?$CTextT@D@@ABV1@0@Z)  
referenced in function "class CTextT<char> __cdecl operator+(class CTextT<char> const &,class CTextT<char> const &)" (??H@YA?AV?$CTextT@D@@ABV0@0@Z)

 1>.DebugUnitTestText.exe : fatal error LNK1120: 1 unresolved externals

If I place the code in the Text.h it compiles fine. But I do not want to do this because I want to keep declaration clean from implementation. I can't figure why linker is complaining in this case when the function is outside the class? This is the only problem and the class is very big and there are other friend functions returning CTextT.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Of course it does give a linker error. The add() function you made a friend isn't a function template! It is a non-template function declared inside a class template. As a result, you won't be able to define this function as a template, either. You can directly define it at the friend declaration.

The alternative is to declare the function template prior to the class template. Of course, this requires a declaration of the class template, too. The following should work:

template <typename T> class CTextT;
template <typename T> CTextT<T> add(CTextT<T> const&, CTextT<T> const&);
template <typename T>
class CTextT
{
    friend CTextT<T> add<>(CTextT<T> const&, CTextT<T> const&);
    // ...
};

Now the template definition you have give should work.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...