This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: Is this legal C++?


> which is telling me that I should have written
> 
>   (this->*C::oper) (x, y);
> 
> Now I find this somewhat surprising.  Why doesn't the "implicit this"
> syntactic sugar extend to an implicit ->* for references to
> pointer-to-member-function members?

It does use the 'implicit this' already, to fetch C::oper. In fact,
you don't need to qualify oper as a member of C, since it is already
known as such using the implicit 'this':

   (this->*oper) (x, y);

To not use the implicit this you are already using, you could write
something like this

void
C::operate (C* other, int x, int y)
{
  (this->*other->oper) (x, y);
}

I.e. you fetch the oper member of the other object, and then apply it
as a pointer-to-member of this object. If you had the extension you
wanted, it would apply the implicit this *twice*.

> I can't find anything relevant in the standard.

You have to look for the place where it allows you to omit the this in
member accesses inside a method. This is explained in 9.3.1/2. It
means that

   foo->*bar

is equivalent to

   foo->*((*this).bar)

if bar turns out to be a member of this (likewise for foo, of course).
No similar shortcut is mentioned for pointer-to-member derefencing, so
this is not part of standard C++.

Please note that the proposed extension would not work. If I
understand correctly, a plain

  bar (something)

is requested as a short-cut for

  (this->*((*this).bar)) (something)

Of course, the (something) is not needed, the same would apply to
pointer-to-data-member. Now, consider

class C {
private:
  int C::*oper;

public:
  void operate (int C::*, int, int);
};

void
C::operate (int C::* x, int y, int z)
{
  oper = x;
  this->*oper = y;
}

If you hade the implicit double-this feature, then 'oper' in the first
assignment would really be of type 'int' (because of the implicit
dereference), and you could not assign to the pointer-to-data-member.

> Also, note that G++ insists on the first pair of parentheses;
> 
>   this->*C::oper (x, y);
> 
> gets the same error.

Yes, as Alexandre points out, this is a precedence problem. It would
work if you write

class C {
private:
  int C::*oper(int x,int y);

public:
  void operate (int, int);
};

void
C::operate (int x, int y)
{
  this->*oper(x,y);
}

in which case you dereference the pointer-to-int-member returned from
oper; ignoring the dereferenced value.

Regards,
Martin


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]