Why does the pointer to method dereference operator in C++ have such low priority?

Viewed 281

The pointer to member dereference operator (.* and ->*) in C++ is of operator precedence 4, while the function call operator is of precedence 2. This pretty much guarantees that parenthesis will be required:

#include <iostream>

struct A {
    int b;

    int func1( int a ) { return a+b+1; }
    int func2( int a ) { return 2*a+b; }
};

int main() {
    A a;

    a.b = 3;

    int (A::*ptr)(int);

    ptr = &A::func1;
    std::cout<<
            (a.*ptr) // <- these parenthesis
                ( 2 ) << "\n";
}

It seems to me that defining .* as priority 2 would (with left to right associativity) negate the need of the parenthesis with no obvious ill side effects.

What was the reason for choosing this priority?

2 Answers

I don't know for sure, but remember that the following code is valid:

const double x = 2.*3 + 4; // (2.0 * 3) + 4

It's possible that making .* have different precedence would have unacceptably complicated the tokenisation stage.

Whatever the reason, it's been this way since the 1980s, and CFront 2.0 (doc, page 22). Unfortunately no explicit rationale was given at that time, nor in any other historical document that I can find.

Consider data members:

struct A
{
    int X;
    int* pointer;
};

int main()
{
  int A::*ptr_i;
  ptr_i = &A::X;
  a.*ptr_i = 10;  // Not needed

  int T;
  a.pointer = &T;
  *a.pointer = 20; // Not needed

  int* A::*ptr_ip;
  ptr_ip = &A::pointer;
  *(a.*ptr_ip) = 10;  //  NEEDDED

  int V;
  a.*ptr_ip = &V;
  *(a.*ptr_ip) = 20; // Modifies V, NEEDED

  // Goes interesting..
  A* ap = &a;
  ap->*ptr_ip = &V;
 *(ap->*ptr_ip) = 100;
}

I would say this is simplified. If we add more complicated function pointers, then it becomes more clumsy, and hence such precedence rules are needed.

Related