Title
Access and surrogate call functions
Status
cd1
Section
12.2.2.2.3 [over.call.object]
Submitter
Andrei Iltchenko

Created on 2001-04-16.00:00:00 last changed 196 months ago

Messages

Date: 2003-10-15.00:00:00

[Voted into WP at October 2003 meeting.]

Date: 2002-10-15.00:00:00

Proposed resolution (revised October 2002):

In 12.2.2.2.3 [over.call.object] paragraph 2, replace the last sentence

Similarly, surrogate call functions are added to the set of candidate functions for each conversion function declared in an accessible base class provided the function is not hidden within T by another intervening declaration.

with

Similarly, surrogate call functions are added to the set of candidate functions for each conversion function declared in a base class of T provided the function is not hidden within T by another intervening declaration.

Replace 12.2.2.2.3 [over.call.object] paragraph 3

If such a surrogate call function is selected by overload resolution, its body, as defined above, will be executed to convert E to the appropriate function and then to invoke that function with the arguments of the call.
by
If such a surrogate call function is selected by overload resolution, the corresponding conversion function will be called to convert E to the appropriate function pointer or reference, and the function will then be invoked with the arguments of the call. If the conversion function cannot be called (e.g., because of an ambiguity), the program is ill-formed.

Date: 2002-10-15.00:00:00

Notes from October 2002 meeting:

It was suggested that the ambiguity check is done as part of the call of the conversion function.

Date: 2002-04-15.00:00:00

Notes from 4/02 meeting:

There was some concern about whether 6.5.2 [class.member.lookup] (or anything else, for that matter) actually defines "ambiguous base class". See issue 39. See also issue 156.

Date: 2001-11-09.00:00:00

According to 12.2.2.2.3 [over.call.object] paragraph 2, when the primary-expression E in the function call syntax evaluates to a class object of type "cv T", a surrogate call function corresponding to an appropriate conversion function declared in a direct or indirect base class B of T is included or not included in the set of candidate functions based on class B being accessible.

For instance in the following code sample, as per the paragraph in question, the expression c(3) calls f2, instead of the construct being ill-formed due to the conversion function A::operator fp1 being inaccessible and its corresponding surrogate call function providing a better match than the surrogate call function corresponding to C::operator fp2:

    void  f1(int)  {   }
    void  f2(float)  {   }
    typedef void  (* fp1)(int);
    typedef void  (* fp2)(float);

    struct  A  {
       operator fp1()
       {   return  f1;   }
    };

    struct  B :  private A  {   };

    struct  C :  B  {
       operator  fp2()
       {   return  f2;   }
    };

    int  main()
    {
       C   c;
       c(3);  // f2 is called, instead of the construct being ill-formed.
       return  0;
    }

The fact that the accessibility of a base class influences the overload resolution process contradicts the fundamental language rule (6.5 [basic.lookup] paragraph 1, and 12.2 [over.match] paragraph 2) that access checks are applied only once name lookup and function overload resolution (if applicable) have succeeded.

History
Date User Action Args
2008-10-05 00:00:00adminsetstatus: wp -> cd1
2004-04-09 00:00:00adminsetmessages: + msg1021
2003-11-15 00:00:00adminsetstatus: ready -> wp
2003-04-25 00:00:00adminsetstatus: review -> ready
2002-11-08 00:00:00adminsetmessages: + msg740
2002-05-10 00:00:00adminsetmessages: + msg628
2001-11-09 00:00:00adminsetmessages: + msg560
2001-11-09 00:00:00adminsetstatus: open -> review
2001-04-16 00:00:00admincreate