Implicit conversion to pointer type when using pointer operators

Consider the following code:

struct X { int x; }; X xInstance; class A { public: operator X*() { return &xInstance; } }; int main() { A a; *a = X(); // ok a[0] = X(); // ok // a->x = 0; // error } 

A has an implicit conversion to a pointer type. I am trying to use it in three contexts in which a pointer is required; the first two lines are accurate, but trying to reference the struct X field to operator-> , relying on an implicit conversion to X* , does not work. Why is this? Conceptually, how operator[] differs from operator-> in this context?

Tested with g++ 6.3.0 and VC ++ 2017.

+7
c ++ pointers
source share
1 answer

Standard Section 13.6 lists "candidate operator functions" that represent built-in operators for the purpose of overload resolution. When at least one subexpression of the @ operator has a class or type of enumeration, the list of functions considered to resolve overloading is a union of the search for non-members operator@ , the search for the operator@ element and these functions of the candidate operator.

For most operators, the functions of the candidate operator are general enough to represent all types allowed by the built-in operator. For example,

For each cv-qualified or cv-unqualified type of object T, there are candidate operator functions of the form

 T& operator*(T*); 

For each cv-qualified or cv-unqualified type of object T, there are candidate operator functions of the form

 T& operator[](T*, std::ptrdiff_t); T& operator[](std::ptrdiff_t, T*); 

When you write *a or a[0] , the corresponding candidate operator function wins overload resolution, subexpressions are converted to argument types of the candidate operator function, and then the usual built-in operator rules are applied.

However, the section does not list any functions of the candidate operator-> for operator-> . Therefore, if a is of class type, the only possible function for a->x is to search for the a.operator->() element. (Non-member search does not apply to operator-> , which should always be a member function.)

+6
source share

All Articles