Member Function Templates is translated into Chinese as a Member Function template. I personally saw this in the source code of STL auto_ptr, and I didn't quite understand it at the time; over the past few days, I 've flipped through "More Effective C ++". I just saw the details described above and found some information to summarize it.
To better illustrate the problem, we define a Smart Pointer (Smart Pointer, which is just an example here, so the definition is incomplete and imperfect ), suppose we have three classes: MusicProduct, CD, and MP3. The relationships between classes are as follows:
The smart pointer SmartPtr we define is as follows:
Template <class T>
Class SmartPtr
{
Public:
Explicit SmartPtr (T * realPtr = NULL): pointee (realPtr ){}
T * operator-> () const
{
Return pointee;
}
T & operator * () const
{
Return * pointee;
}
Private:
T * pointee;
};
Now there is a playback function:
Void displayAndPlay (const SmartPtr <MusicProduct> & pmp, int times)
{
For (int I = 1; I <= times; ++ I)
{
Pmp-> displayTitle ();
Pmp-> play ();
}
}
Will there be any problems with the following calls?
Int main (int argc, char ** argv)
{
CD * cd = new CD ("beyond live cd ");
MP3 * mp3 = new MP3 ("BEYOND MP3 ");
SmartPtr <CD> cdMusic (cd );
SmartPtr <MP3> mp3Music (mp3 );
DisplayAndPlay (cdMusic, 10 );
DisplayAndPlay (mp3Music, 10 );
Return 0;
}
An error occurs during actual compilation. the following error is prompted in Visual Studio 2008:
1> error C2664: "displayAndPlay": parameter 1 cannot be converted from "SmartPtr <T>" to "const SmartPtr <T> &"
1>
1> [
1> T = CD
1>]
1> and
1> [
1> T = MusicProduct
1>]
1> ......
The prompt "SmartPtr" cannot be converted to "const SmartPtr &". In the compiler's eyes, SmartPtr and SmartPtr are completely irrelevant and there is no inheritance relationship between them. We can write an implicit type conversion, but the actual operation is not ideal. As mentioned above, STL auto_ptr uses Member
Function Templates (member Function template) technology. We can add the implementation code of the member function template in the definition of SmartPtr, as follows:
Template <class T>
Class SmartPtr
{
Public:
Explicit SmartPtr (T * realPtr = NULL): pointee (realPtr ){}
T * operator-> () const
{
Return pointee;
}
T & operator * () const
{
Return * pointee;
}
// Member Function Templates
Template <class newType>
Operator SmartPtr <newType> ()
{
Return SmartPtr <newType> (pointee );
}
Private:
T * pointee;
};
Then you can compile and run the program normally. It looks amazing. Let's take a look at the explanation of More Effective C ++:
Please note that this is not a magic, but it is very similar to magic. Assume that the compiler has a smart pointer to the T object, which converts the object to a smart pointer pointing to the "T base class. The compiler first checks the definition of the SmartPtr class to see if it declares a clear type conversion character, but it does not. The compiler then checks whether a member function template exists and can be converted into The expected type conversion by instances. It finds such a template (with the Form Type parameter newType), so it binds newType to the base class type of T to instantiate the template. At this time, the only problem is whether the code of the instantiated member function can be compiled: the constructor that transfers the pointer pointee to the smart pointer pointing to the "T base class" must be legal. Pointee refers to the T type, and it must be legal to convert the pointer to its base class (public or protected) object. Therefore, the type conversion operator can be compiled, the smart pointer pointing to T can be implicitly converted to the smart pointer pointing to the "T base class.
Note:
1. Member Function Templates is a new feature of C ++. Some compilers may not support this feature, such as VC6. during compilation, it seems that the newly added Member Function Templates code is completely ignored. The following error is still prompted:
-------------------- Configuration: MftDemo-Win32 Debug --------------------
Compiling...
MemFunTmp. cpp
G: \ w7documents \ visual studio 6.0 \ projects \ mftdemo \ memfuntmp. cpp (87): error C2664: 'displayandplay ':
Cannot convert parameter 1 from 'class SmartPtr <class CD> 'to 'const class SmartPtr <class MusicProduct> &'
Reason: cannot convert from 'class SmartPtr <class CD> 'to 'const class SmartPtr <class MusicProduct>'
No constructor cocould take the source type, or constructor overload resolution was ambiguous
G: \ w7documents \ visual studio 6.0 \ projects \ mftdemo \ memfuntmp. cpp (88): error C2664: 'displayandplay ':
Cannot convert parameter 1 from 'class SmartPtr <class MP3> 'to 'const class SmartPtr <class MusicProduct> &'
Reason: cannot convert from 'class SmartPtr <class MP3> 'to 'const class SmartPtr <class MusicProduct>'
No constructor cocould take the source type, or constructor overload resolution was ambiguous
An error occurred while executing cl.exe.
MftDemo.exe-1 error (s), 0 warning (s)
Author: "LoveBeyond"