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 = ⁢
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?
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. –
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. –
@ 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. –