Implicit conversion to pointer type when applying pointer-related operators
c++, pointers
Solution
Standard section 13.6 lists the "candidate operator functions" that represent the built-in operators for purposes of overload resolution. When at least one subexpression of an operator @ has class or enum type, the list of functions considered for overload resolution is the union of the non-member lookup of `operator@`, the member lookup of `operator@`, and these candidate operator functions.
For most operators, the candidate operator functions are general enough to represent all the types permitted by the built-in operator. For example,
For every cv-qualified or cv-unqualified object type T, there exist candidate operator functions of the form
T& operator*(T*);
For every cv-qualified or cv-unqualified object type T there exist 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, the subexpressions are converted to the argument types of the candidate operator function, and then the ordinary built-in operator rules apply.
However, the section does not list any candidate operator functions for `operator->`. So if `a` has class type, the only possible function for `a->x` is the member lookup of `a.operator->()`. (Non-member lookup does not apply to `operator->`, which must always be a member function.)
Problem
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 attempt to use it in three contexts in which a pointer is required; the two first lines are fine, but attempting to reference a field of `struct X` through `operator->` relying on the implicit conversion to `X*` does not work. Why is that? Conceptually, how is `operator[]` different from `operator->` in this context? Tested with `g++` 6.3.0 and VC++ 2017.