(&C::f)() with nonstatic members
Section [over.match.call]
Steve Adamczyk

Created on 1999-08-26.00:00:00 last changed 162 months ago


Date: 2002-10-15.00:00:00

[Moved to DR at October 2002 meeting.]

Date: 2001-04-15.00:00:00

Proposed resolution (04/01):

  1. Change the indicated text in [over.match.call] paragraph 3:

    The fourth case arises from a postfix-expression of the form &F, where F names a set of overloaded functions. In the context of a function call, the set of functions named by F shall contain only non-member functions and static member functions. [Footnote: If F names a non-static member function, &F is a pointer-to-member, which cannot be used with the function call syntax.] And in this context using &F behaves the same as using &F is treated the same as the name F by itself. Thus, (&F)(expression-listopt) is simply (F)(expression-listopt), which is discussed in [over.call.func]. If the function selected by overload resolution according to [over.call.func] is a nonstatic member function, the program is ill-formed. [Footnote: When F is a nonstatic member function, a reference of the form &A::F is a pointer-to-member, which cannot be used with the function-call syntax, and a reference of the form &F is an invalid use of the "&" operator on a nonstatic member function.] (The resolution of &F in other contexts is described in 12.3 [over.over].)
Date: 2004-09-10.00:00:00 [over.match.call] paragraph 3 says that when a call of the form

is written, the set of overloaded functions named by C::f must not contain any nonstatic member functions. A footnote gives the rationale: if a member of C::f is a nonstatic member function, &C::f is a pointer to member constant, and therefore the call is invalid.

This is clear, it's implementable, and it doesn't directly contradict anything else in the standard. However, I'm not sure it's consistent with some similar cases.

In 12.3 [over.over] paragraph 5, second example, it is made amply clear that when &C::f is used as the address of a function, e.g.,

   int (*pf)(int) = &C::f;
the overload set can contain both static and nonstatic member functions. The function with the matching signature is selected, and if it is nonstatic &C::f is a pointer to member function, and otherwise &C::f is a normal pointer to function.

Similarly, [over.call.func] paragraph 3 makes it clear that

is a valid call even if the overload set contains both static and nonstatic member functions. Overload resolution is done, and if a nonstatic member function is selected, an implicit this-> is added, if that is possible.

Those paragraphs seem to suggest the general rule that you do overload resolution first and then you interpret the construct you have according to the function selected. The fact that there are static and nonstatic functions in the overload set is irrelevant; it's only necessary that the chosen function be static or nonstatic to match the context.

Given that, I think it would be more consistent if the (&C::f)() case would also do overload resolution first. If a nonstatic member is chosen, the program would be ill-formed.

Date User Action Args
2008-10-05 00:00:00adminsetstatus: wp -> cd1
2003-04-25 00:00:00adminsetstatus: dr -> wp
2002-11-08 00:00:00adminsetmessages: + msg779
2002-11-08 00:00:00adminsetstatus: ready -> dr
2002-05-10 00:00:00adminsetstatus: review -> ready
2001-05-20 00:00:00adminsetmessages: + msg487
2001-05-20 00:00:00adminsetstatus: open -> review
1999-08-26 00:00:00admincreate