
Boost : 
From: John Max Skaller (skaller_at_[hidden])
Date: 20010520 16:48:14
Jens Maurer wrote:
> For the point in question here, declaring the function
> first is not a viable option:
>
> namespace N {
> template<class T>
> class X {
> friend void f(T x) { ... }
> }
> }
>
> X<int> x;
>
> makes exactly N::f(int x) (nontemplate) available for Koenig
> lookup, and no other overload of N::f.
No it does not. f(1) will not search N, nor even
class X, since 'int' is not defined in N or class X.
But consider:
namespace N {
class Y {};
template<class T>
class X { friend void f(T){} };
}
N::Y y;
f(y);
Without the prior declaration of f outside the class X,
the lookup for f will fail. The question is whether
it will work, if one writes:
X<N::Y> x;
N::Y y;
f(y);
instead. I don't know the answer, but there is no issue
if you actually declare the function in N: both cases succeed.
So this is the right way to do it. What is the problem
with this?
The only case I can think of is this:
namespace B { class U {}; void f(U); }
namespace N { class Y : public B::U {}
...
}
Here, a lookup for f(Y) needs to fail in N, so it
can succeed in B with an upcast on the argument.
Placing a declaration of f directly in N will
prevent this happening. With the inline friend
technique, assuming it actually works as you think,
there is no f there. BUT if ANY instance of f is there,
you're stuffed: that f will be found, and will not
match.
So the 'inline friend' technique is not only
problematic, it is a very serious design error
if it actually works. [AFAIK, it doesn't actually
work]
 John (Max) Skaller, mailto:skaller_at_[hidden] 10/1 Toxteth Rd Glebe NSW 2037 Australia voice: 61296600850 checkout Vyper http://Vyper.sourceforge.net download Interscript http://Interscript.sourceforge.net
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk