开发者

friend function

What does the following mean (especially the highlighted portion)? Why is the expression 'f(a)' treated as a 'cast expression'?

C++03 $3.4.开发者_JS百科/3- "The lookup for an unqualified name used as the postfix-expression of a function call is described in 3.4.2. [Note: for purposes of determining (during parsing) whether an expression is a postfix-expression for a function call, the usual name lookup rules apply. The rules in 3.4.2 have no effect on the syntactic interpretation of an expression. For example,

typedef int f;
struct A {
friend void f(A &);
operator int();
void g(A a) {
f(a);
}
};

The expression f(a) is a cast-expression equivalent to int(a). Because the expression is not a function call, the argument-dependent name lookup (3.4.2) does not apply and the friend function f is not found. ]"

Any thoughts?


It means that the parser first determines whether the expression before the parentheses is an id or a postfix-expression. In this case, it sees f, and the nearest f defined is typedef int f - therefore it concludes the expression is interpreted as int(a) and no Koenig lookup is performed.

Let's have this code (you an try it online: http://ideone.com/clone/eRKvP)

typedef int f;
namespace x {
  struct A {
    friend void f(A &);
    //friend void f(); // # 1
    operator int();
    void g(A a) {
      //void f();  // # 2
      (void)f(a); // # 3
    }
  };
}

Had you declared an (unrelated) function f visible from g, it would be interpreted as a function call and Koenig lookup would find the correct overload (see line #2).

The friend declaration of f should not apply here, because

11.4/1: ... The name of a friend is not in the scope of the class,

However, what's disturbing me, is that uncommenting #1 makes the compiler (gcc in this case) call x::f(A&) too. Not sure why is that. [In Comeau Online compiler, it works as expected (eg. #1 doesn't influence line #3). The latest beta version has problems compiling this code, though.]

PS: As noted by litb, the rules in C++0x are a little different:

3.4.2/3:

Let X be the lookup set produced by unqualified lookup (3.4.1) and let Y be the lookup set produced by argument dependent lookup (defined as follows). If X contains

  • a declaration of a class member, or
  • a block-scope function declaration that is not a using-declaration, or
  • a declaration that is neither a function or a function template

then Y is empty. Otherwise Y is the set of declarations found in the namespaces associated with the

The bold item will make the compiler only consider void f() and fail for too many arguments.

It seems to have been introduced by the resolution of issue 218.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜