Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Result of ‘operator->()’ yields non-pointer result

Tags:

c++

c++11

In this code:

while(k != listeners.getLength()) {
    if(listeners[k] != nullptr) {
        listeners[k]->onNewMessage(*newMessage);
    }
    k++;
}

The compiler does not like the -> at all.

listeners[k] is a class with an operator->() that is both public and defined, returning a reference to a type with a (virtual) method onNewMessage.

Changing it to:

while(k != listeners.getLength()) {
    if(listeners[k] != nullptr) {
        listeners[k].operator ->().onNewMessage(*newMessage);
    }
    k++;
}

works.

It used to work. I added some boolean operators (== and != to the type returned by reference of listeners[k]). I also added a constructor for a ::std::nullptr_t type. I can't see any reason why these would cause a problem, and the error mentions no ambiguity so it's not that it has too many options.

Why is there a problem here?

Addendum

To clarify the structure is as follows:

List<PtrWrapper<LogListener>> listeners;

T& List<T>::operator[](int); and a const definition to go with it.

T& PtrWrapper<T>::operator->(); and a const version to go with it.

LogListener has a virtual method onNewMessage.

So listeners[k] is a PtrWrapper<LogListener>&.

like image 649
Alec Teal Avatar asked Nov 30 '22 11:11

Alec Teal


1 Answers

The operator->() is a bit of an odd-ball: although it can return a non-pointer type, the resulting type would need to overload the operator->(), too! Basically, when the compiler sees a use of an overloaded operator->() it will keep applying operator->()s until the result is a pointer. Once a pointer is obtained, it knows how to access the corresponding member.

It is an error if repeated application of operator->() leads to a non-pointer type which doesn't overload operator->().

like image 75
Dietmar Kühl Avatar answered Dec 15 '22 23:12

Dietmar Kühl