Le moyen le plus portable et le plus fiable pour obtenir l’adresse de la variable en C ++

Utiliser & pour obtenir l’adresse d’une variable peut être problématique si le type de variable a surchargé l’ operator&() . Par exemple, _com_ptr_ a l’ operator&() surchargé avec un effet secondaire de modification de l’object.

Maintenant, j’ai un ensemble compliqué de modèles avec des fonctions comme celle-ci:

 template void process( const T* object ) { //whatever } template void tryProcess( T& object ) { process( &object ) } 

Dans tryProcess() je dois obtenir un pointeur T* contenant l’adresse de l’object réel de type T

L’implémentation ci-dessus de tryProcess() ne fonctionnera correctement que si la class T n’a pas surchargé l’ operator&() . Donc, si j’appelle tryProcess<_com_ptr_>() je peux obtenir des résultats inattendus: l’ operator&() surchargé operator&() est déclenché.

Dans une autre question, la solution suivante est suggérée :

 template T* getAddress( T& object ) { return reinterpret_cast( &reinterpret_cast( object ) ); } 

Avec une telle fonction, je peux implémenter tryProcess() comme suit:

 template void tryProcess( T& object ) { process( getAddress( object ) ) } 

et aura toujours le même comportement, que la class T ait l’ operator&() surchargé. Cela n’introduit aucune surcharge avec les optimisations sur Visual C ++ 7 – le compilateur obtient ce qu’il doit faire et obtient simplement l’adresse de l’object.

Comment portable et standard-compilant est cette solution au problème? Comment cela pourrait-il être amélioré?

C’est la plainte standard. La question a été scope à l’attention du comité ISO C ++ à propos des problèmes d’implémentation offsetof implémentations. Parmi les solutions envisagées, citons le renforcement de la définition de POD ou l’ajout d’une ressortingction supplémentaire sur les types à utiliser avec offsetof . Ces solutions ont été rejetées lorsque la solution reinterpret_cast été mise en place. Etant donné que cela offrait une solution conforme au standard, le comité n’a pas offsetof nécessaire d’append des exigences supplémentaires à l’ offsetof et a laissé des correctifs pour les implémentations.

Boost addressof est implémenté avec cette astuce addressof donc je dirais que c’est probablement portable et conforme à la norme.

Ici vous pouvez voir le code en question.