38 votes

Est "reliaison" références en C++ comme ce légal?

Est la suivante juridique en C++?

Aussi loin que je peux dire, Reference a un trivial destructeur, de sorte qu'il devrait être légal.
Mais je pensais que les références ne peuvent pas être reprise légalement... peuvent-ils?

template<class T>
struct Reference
{
    T &r;
    Reference(T &r) : r(r) { }
};

int main()
{
    int x = 5, y = 6;
    Reference<int> r(x);
    new (&r) Reference<int>(y);
}

18voto

Mark Ransom Points 132545

Vous n'êtes pas reliaison une référence, vous êtes en train de créer un nouvel objet dans la mémoire d'une autre avec un placement de nouvelles. Depuis le destructeur de l'objet ancien n'a jamais été exécuté, je pense que ce serait un comportement indéfini.

11voto

Charles Bailey Points 244082

Il n'y a pas de référence en cours de rebond dans votre exemple. La première référence (construit sur la ligne deux, avec le nom de l' r.r) est lié à l' int notée en x pour l'ensemble de sa durée de vie. Cette référence est la durée de vie est terminé lorsque le stockage de son objet contenant est réutilisée par la mise en place de la nouvelle expression sur la ligne trois. L'objet de remplacement contient une référence qui est lié à la y pour l'ensemble de sa durée de vie qui dure jusqu'à la fin de son champ d'application - la fin de l' main.

4voto

dyp Points 19641

Je crois que j'ai trouvé la réponse dans un passage en dessous de la "cité" celui qui parle trivial dtor / dtor effets secondaires, à savoir [de base.la vie]/7:

Si, après la durée de vie d'un objet est terminé, et avant le stockage de l'objet occupés est réutilisé ou libérés, un nouvel objet est créé à l'emplacement de l'objet d'origine occupé, un pointeur pointant sur l'objet original, une référence qui indique l'objet d'origine, ou le nom de l'objet original sera automatiquement référence à l'objet nouveau et, une fois la durée de vie du nouvel objet a commencé, peut être utilisé pour manipuler le nouvel objet, si:

  • le stockage pour le nouvel objet exactement superpose à l'emplacement de l'objet d'origine occupé, et

  • le nouvel objet est de même type que l'objet d'origine (en ignorant le niveau supérieur de la cv-qualificatifs), et

  • le type de l'objet d'origine n'est pas const-qualifiés, et, si un type de classe, ne contient pas de tout non-membre de données statiques, dont le type const qualifié ou un type de référence, et

  • l'objet d'origine était un dérivé de l'objet de type T et le nouvel objet est un objet dérivé de type T (qui est, ils ne sont pas de la classe de base sous-objets).

En réutilisant le stockage, la durée de vie de l'objet d'origine [de base.la vie]/1

La durée de vie d'un objet de type T se termine lorsque:

  • si T est un type de classe avec un non-trivial destructeur, le destructeur de l'appel commence, ou

  • le stockage de l'objet occupe de les réutiliser ou libéré.

Donc, je pense que [de base.la vie]/7 traite de la situation

Reference<int> r(x);
new (&r) Reference<int>(y);

où nous la fin de la durée de vie de l'objet dénoté par r, et de créer un nouvel objet, au même endroit.

En tant que Reference<int> est un type de classe de référence avec un membre de données, les exigences de la [base.la vie]/7 sont pas remplies. C'est, r pourrait même ne pas se référer à l'objet nouveau, et nous ne pouvons pas l'utiliser pour "manipuler" cet objet nouvellement créé (je interpréter ce "manipuler" également en lecture seule accès).

0voto

marcin_j Points 12237

Probablement, ce n'est pas la réponse à votre question, mais vous pouvez faire usage de std::reference_wrapper, je pense qu'il accomplit tout à fait le même que votre code:

#include <iostream>
#include <functional>
int main()
{
    int x = 5, y = 6;    
    std::reference_wrapper<int> rf(x);
    std::cout << rf << std::endl;
    rf = y;
    std::cout << rf << std::endl;
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X