I was perusing section 13.5 after refuting the notion that built-in operators do not participate in overload resolution, and noticed that there is no section on operator->*. It is just a generic binary operator.
Its brethren, operator->, operator*, and operator[], are all required to be non-static member functions. This precludes definition of a free function overload to an operator commonly used to obtain a reference from an object. But the uncommon operator->* is left out.
In particular, operator[] has many similarities. It is binary (they missed a golden opportunity to make it n-ary), and it accepts some kind of container on the left and some kind of locator on the right. Its special-rules section, 13.5.5, doesn't seem to have any actual effect except to outlaw free functions. (And that restriction even precludes support for commutativity!)
So, for example, this is perfectly legal (in C++0x, remove obvious stuff to translate to C++03):
#include <utility>
#include <iostream>
#include <type_traits>
using namespace std;
template< class F, class S >
typename common_type< F,S >::type
operator->*( pair<F,S> const &l, bool r ) {
return r? l.second : l.first;
}
template< class T >
T &
operator->*( pair<T,T> &l, bool r ) {
return r? l.second : l.first;
}
template< class T >
T &
operator->*( bool l, pair<T,T> &r ) {
return l? r.second : r.first;
}
int main() {
auto x = make_pair( 1, 2.3 );
cerr << x->*false << " " << x->*4 << endl;
auto y = make_pair( 5, 6 );
y->*(0) = 7;
y->*0->*y = 8; // evaluates to 7->*y = y.second
cerr << y.first << " " << y.second << endl;
}
I can certainly imagine myself giving into temp[la]tation. For example, scaled indexes for vector:
v->*matrix_width[2][5] = x;
Did the standards committee forget to prevent this, was it considered too ugly to bother, or are there real-world use cases?