A question from the programmer interview book.
Describes a friend overload of a template class, implemented in C + + code?
This actually examines the following questions:
1. Writing of template classes
2. Writing of friend function in template class
3. When will the friend reload be used? The answer is the various operators in C + +. The most typical is the output operator <<.
The answers given in the book are as follows:
#include <iostream>using namespace Std;template<class t> class Test;template<class t> Ostream & operator<< (Ostream & Out,const test<t> &obj); Template<class t> class Test{private:int num; public:test (int n=0) {num=n;} Test (const test <T> ©) {num=copy.num;} Note adding "<>" after "<<" means this is a function template friend ostream& operator<< <> (ostream & Out,const test< T> &obj);}; Template<class t> ostream& operator<< (ostream & out,const test<t> &obj) {out<< Obj.num;return out;} int main () {test<int> T (2); Cout<<t;return 0;}
Just to the above comment on which line is not very understanding and then turned the "C + + Primer", found that the book on the issue is very detailed. Copy it over:
Friend declaration in a class template
There are three friend declarations that can appear in a class template, each declaring a friend relationship with one or more entities:
(1) A friend declaration of a normal non-template or function that grants a friend relationship to a class or function that is explicitly specified
(2) A friend declaration of a class template or function template that grants access to all the instances that are destined
(2) A friend declaration that grants access only to a specific instance of a class template or function template
1. Ordinary Friends
A non-template class or non-template function can be a friend of a class template:
Template<class Type> class bar{//is authorized to general class and or function friend class folbar;friend void Fcn ();};
This statement means that the members of the Folbar and the FCN function can access Privete members and protected members of any instance of the bar class.
2. General template friend
A friend can be a class template or a function template:
Template<class Type> class bar{//authorize any instance of Foo1 or temp1_fcn1 template<class t> friend class foo1;template< Class t> friend void Temp1_fcn1 (const t&);};
These friend declarations use type parameters that are different from the class itself, which refers to the type parameters of Foo1 and temp1_fcn1. In both cases, classes and functions that do not have a number of restrictions are set to friends of bar. Foo1 's friend declaration is that any instance of Foo1 can access a private member of any instance of bar, similarly, any instance of TEMP1_FCN1 can access any instance of bar.
This friend declaration establishes a one-to-many mapping between bar and each instance of its friend Foo1 and TEMP1_FCN1. For each instance of bar, all instances of Foo1 or temp1_fcn1 are friends.
3. Specific template friend relationships
In addition to setting all instances of a template as friends, the class can grant access only to specific instances.
Template<class t> class Foo2;template<class t> void temp1_fcn2 (const t&); Template<class Type> Class bar{//is only authorized for instances where the parameter type is char* friend class Foo2<char *>;friend void Temp1_fcn2<char *> (char * const &);};
Even though Foo2 itself is a class template, a friend relationship extends only to a specific instance of the Foo2 parameter type char*. Similarly, TEMP1_FCN2 's friend declaration is that only a function instance with a parameter type of char* is a friend of the bar class. A specific instance of Foo2 and temp1_fcn2 with a formal parameter type of char* can access each instance of bar.
The following forms of friend declarations are more common:
Template<class t> class Foo3;template<class t> void Temp1_fcn3 (const t&); Template<class Type> Each instance of class Bar{//bar can only access the argument type and Bar the same Foo3 and Temp1_fcn3 instance friend class Foo3<type>;friend void Temp1_fcn3<type > (const Type &);};
These friends define a friend relationship between a specific instance of bar and an instance of Foo3 or temp1_fcn3 that uses the same template argument, and each bar instance has a related Foo3 and temp1_fcn3 friend:
Bar<int> b1;//Its friend is foo3<int> and temp1_fcn3<int>bar<string> bs;//its friend is foo3<string> and temp1_fcn3<string>
Only those versions of Foo3 or TEMP1_FCN3 that have the same template arguments as the given bar instance are friends. Therefore,,foo3<int> can access the private portion of the bar<int>, but cannot access the private portion of the bar<string> or any other bar instance.
4. Declaring Dependencies
When you grant access to all instances of a given template, there is no need for the declaration of that class template or function template to exist in the scope. Essentially, the compiler treats a friend declaration as a declaration of a class or function.
When you want to restrict a friend relationship to a specific instantiation, you must declare the class or function before you can declare it with friend:
Template <class t> class a;template <class t> class B{public:friend class A<t>;//ok,a made a statement friend Class C; Ok,c is a generic class Template<class s> friend Class D;//ok,d is a template and is licensed to friend Class E<t>;//error for all instances of D, Need to declare friend class F<int>;//error, need to declare};
This error can occur in g++:
If you do not tell the compiler beforehand that the friend is a template, the compiler will consider the friend to be a normal non-template class or non-template function.
The above is the "C + + Primer" on the template class in the friend of the description, after understanding these and then look at this problem is very good understanding. According to the 3rd, a specific template friend relationship can understand why the need for <>, is actually <t>, but can only be written in <>.
Depending on the 4th type of dependency you can see why you need to add a statement at the top.
You can then rewrite it in the form of a friend relationship of the 2nd General template, with the following code: But it doesn't feel necessary.
Note that the preceding declaration is not required because, as per the 4th above, access to all instances is not required to be declared beforehand.
<< don't need <> at the back. Because this is preceded by the keyword Template<class tt>.
Note: In order to prevent this symbol from being omitted in the class template or function template in the future, it can be remembered that, for class templates or function templates, there is either Template<class > retouching, or there is a need for <> both.
#include <iostream>using namespace Std;template<class t> class Test{private:int num;public:test (int n=0) { Num=n;} Test (const test <T> ©) {num=copy.num;} Note adding "<>" after "<<" means this is a function template Template<class tt> friend ostream& operator<< (Ostream & Out,const test<tt> &obj);}; Template<class t> ostream& operator<< (ostream & out,const test<t> &obj) {out<< Obj.num;return out;} int main () {test<int> T (2); Cout<<t;return 0;}
Friend overloading of template classes in C + +