Re: Compiler error with friend
On Jan 13, 7:48 pm, Leigh Johnston <le...@i42.co.uk> wrote:
On 13/01/2011 19:38, James Kanze wrote:
On Jan 13, 3:44 pm, Leigh Johnston<le...@i42.co.uk> wrote:
On 13/01/2011 15:26, Adrian wrote:
[...]
Use friend name injection; that should solve your problem
(there is no need to define operator<< at global scope due to
ADL).
I'm not sure about your vocabulary here. What do you mean by
"friend name injection"? The names of a friend used to be
injected into the surrounding scope, but this was removed from
the standard. ADL does do a sort of injection, but this is
limited. (It will work in the case of operator<<. But it can
fail to work in some other special cases. ADT only kicks in
once the compiler has found a function. ADT will add to the
overload set, but it won't be used if the initial overload set
is empty.)
struct foo
{
friend void friend_name_injection(const foo& a) { std::cout <<
a.iPrivateBits; }
public:
foo() : iPrivateBits(42) {}
private:
int iPrivateBits;
};
int main()
{
foo o;
friend_name_injection(o);
}
This doesn't use friend name injection, but ADL. And while this
particular example does seem to work, I had a problem recently
with something very similar, which failed to compile with g++.
(But looking at it, my case was slightly different.)
Friend name injection, as defined in the ARM and other
prestandard documents, would have resulted in
friend_name_injection being found even without ADL (which didn't
exist back then); a friend declaration always injected the name
into the surrounding scope (or back then, in pre namespace days,
file scope).
There's an issue I'm not too sure about (although I know what
compilers actually do, and I don't expect that to change). ADL
is only used for the postfix-expression of a function call. But
the meaning of () is context dependent. Given the expression
friend_name_injection(o), above, how does the compiler decide
whether the () is a function call, or part of an "Explicit type
conversion (functional notation)"? The obvious answer is that
it is a function call, because friend_name_injection is the name
of a function. The compiler cannot find friend_name_injection
(to know that it is function, and not the name of a type) until
it uses ADL, and it cannot use ADL until it knows that
friend_name_injection is not the name of a type.
I think I'll raise the issue in comp.std.c++. Given the
expression `f(a)', all of the compilers I know assume a function
call until proven otherwise, but I can't find anything in the
standard to support this.
Are you claiming that the above code will become illegal in
C++0x? If not then how can it be that friend name injection
is being removed?
No, but the reason it works is ADL, and not friend name
injection.
--
James Kanze