Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implicit conversion to pointer type when applying pointer-related operators

Tags:

c++

pointers

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.

like image 506
user4520 Avatar asked May 01 '17 21:05

user4520


People also ask

What is implicit conversion give an example?

Implicit conversions: No special syntax is required because the conversion always succeeds and no data will be lost. Examples include conversions from smaller to larger integral types, and conversions from derived classes to base classes.

What is implicit type conversion?

Implicit type conversion in C language is the conversion of one data type into another datatype by the compiler during the execution of the program. It is also called automatic type conversion.

How does implicit conversion work c++?

Implicit type conversion also known as automatic type conversion is carried out by the compiler without the need for a user-initiated action. It takes place when an expression of more than one data type is present which in such an instance type conversion takes place to avoid data loss.

How to return the value of a pointer in c++?

To get the value pointed to by a pointer, you need to use the dereferencing operator * (e.g., if pNumber is a int pointer, *pNumber returns the value pointed to by pNumber . It is called dereferencing or indirection).


1 Answers

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.)

like image 72
aschepler Avatar answered Sep 22 '22 15:09

aschepler