Utilisation générale pour retourner des références constantes:
Retourner une référence constante est courant dans les cas où la création ou la destruction d'une copie est coûteuse.
En général, la règle est la suivante : Si le passage et l'utilisation d'une référence sont plus coûteux que la création d'une copie, ne le faites pas. Si on ne vous demande pas un sous-objet, c'est normalement même impossible.
Sinon, il s'agit d'une optimisation de performance valide de retourner des références constantes, qui est transparente pour le code source bien comporté.
Beaucoup de code de modèle retourne des références constantes même lorsque le test ci-dessus n'indique pas, juste pour traiter toutes les spécialisations de manière égale et parce que la fonction est vraiment petite et est presque garantie d'être inlinée de toute façon.
Pour en venir maintenant à l'essence de votre découverte curieuse (je n'ai jamais rien vu de tel jusqu'à présent) :
+ Pas besoin d'une fonction d'accesseur (néanmoins, c'est nul, cela sera de toute façon compilé)
- L'objet est plus gros (les références nécessitent normalement autant d'espace que les pointeurs)
- Besoin potentiel d'une meilleure alignement en raison du point ci-dessus.
- N'a pas de fonctions membres magiques, car le compilateur ne sait pas comment copier les références
- Pour les compilations de débogage, on ne peut pas ajouter de vérifications supplémentaires.
Le même aspect sans ces dommages collatéraux peut être réalisé de la manière suivante d'ailleurs (seules les vérifications supplémentaires pour le débogage restent impossibles) :
template
struct exemple {
exemple(T t): value{t}{}
union{
const T value;
struct{
private:
T value;
friend class exemple;
} _value;
};
};