2012-09-07 1 views
0

J'ai le code suivant:« membre du pointeur » Surchargé « déréférencer » ou les opérateurs ne reçoivent pas courir quand j'ai un pointeur vers un objet

#include <iostream> 

struct Base { 
    int i_; 
}; 

class El : protected Base { 
public: 
    int get_i() const { return i_; } 
    void set_i(int i) { i_ = i; } 
}; 

class It : protected Base { 
public: 
    using pointer = const El*; 
    using reference = const El&; 

    reference operator*() const 
    { 
     return reinterpret_cast<reference>(*this); 
    } 

    pointer operator->() const 
    { 
     return reinterpret_cast<pointer>(this); 
    } 
}; 

int main() 
{ 
    It it; 
    It* itp = &it; 
    std::cout << *****(itp)->get_i() << "\n"; //ERROR 
} 

gcc et Clang ++ ne pas en quelque sorte d'invoquer l'une des operator* ou operator->, donc j'obtiens une erreur It doesn't have member function 'get_i' dans la dernière ligne indépendamment du nombre d'indirections que j'essaie. La norme justifie-t-elle un tel comportement non intuitif?

+0

Le 'reinterpret_cast' de' It' à 'El' est un comportement indéfini. Même si vous l'obtenez pour compiler, il n'y a aucune garantie que le code généré fonctionnera. –

+0

Question supplémentaire: comment faire cela d'une manière qui n'invoque pas UB? J'ai quelques données et je veux avoir deux points de vue. –

+0

@ jons34yp: pourquoi ne pas simplement faire en sorte que 'It' dérive de' El', peut-être en privé? Fondamentalement, vous allez sortir de votre chemin (et briser strict aliasing) juste pour empêcher quelqu'un d'appeler 'get_i()' sur un 'It'. Mais peut-être que dans votre vrai code, 'El' a des opérateurs qui s'affrontent avec ceux de' It'. Normalement, vous écrivez des itérateurs pour faire référence à des éléments plutôt que chaque élément étant son propre itérateur, donc je suppose que quelque chose de drôle se passe. –

Répondre

5

Priorité d'opérateur: -> se lie plus étroitement, donc est appliqué au pointeur itp.

Lorsque vous surchargez operator->, que n'a pas effet le sens de operator-> appliqué à un pointeur à votre classe. Vous voulez (*itp)->get_i();, je pense.

+0

Oh génial (facepalm) :( –

Questions connexes