Defining ordinary friend functions in class templates needs special attention:
template
class Creator {
friend void appear() { // a new function ::appear(), but it doesn't
… // exist until Creator is instantiated
}
};
Creator miracle; // ::appear() is created at this point
Creator oops; // ERROR: ::appear() is created a second time!
In this example, two different instantiations create two identical definitions—a direct violation of the ODR
We must therefore make sure the template parameters of the class template appear in the type of any friend function defined in that template (unless we want to prevent more than one instantiation of a class template in a particular file, but this is rather unlikely). Let's apply this to a variation of our previous example:
template
class Creator {
friend void feed(Creator*){ // every T generates a different
… // function ::feed()
}
};
Creator one; // generates ::feed(Creator*)
Creator two; // generates ::feed(Creator*)
Disclaimer: I have pasted this section from C++ Templates: The Complete Guide / Section 8.4