simeonz wrote: |
---|
You've got to be kidding me. I didn't know this "friend defined inside a class" monster. Could you explain what part of the code can see it and use it? Does the code get inlined? |
Friend functions can be defined inside template declarations, but it will not get istantiated until
a concrete class of the template is actually created.
here is some info from
'templates - the complete guide'
However, an interesting effect occurs when a friend function is defined in a class template
because anything that is only declared in a template isn't a concrete entity until
the template is instantiated. Consider the following example:
1 2 3 4 5 6
|
template <typename T>
class Creator {
friend void appear() { // a new function ::appear(), but it doesn't
… // exist until Creator is instantiated
}
};
|
1 2
|
Creator<void> miracle; // ::appear() is created at this point
Creator<double> oops; // ERROR: ::appear() is created a second time!
|
In this example, two different instantiations create two identical definitions—a direct violation of the ODR (see Appendix A).
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:
1 2 3 4 5 6
|
template <typename T>
class Creator {
friend void feed(Creator<T>*){ // every T generates a different
… // function ::feed()
}
};
|
1 2
|
Creator<void> one; // generates ::feed(Creator<void>*)
Creator<double> two; // generates ::feed(Creator<double>*)
|
In this example, every instantiation of Creator generates a different function.
Note that even though these functions are generated as part of the instantiation of a template,
the functions themselves are ordinary functions, not instances of a template.
Also note that because the body of these functions is defined inside a class
definition, they are implicitly inline.
Hence, it is not an error for the same function to be generated in two different translation units.