$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
From: John Max Skaller (skaller_at_[hidden])
Date: 2001-05-20 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) (non-template) 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: 61-2-9660-0850 checkout Vyper http://Vyper.sourceforge.net download Interscript http://Interscript.sourceforge.net