8
votes

Interdire la prise de pointeur / référence à la const à un objet temporaire en C ++ (no c ++ 0x)

Je suis confronté au problème suivant. Considérez la classe suivante: xxx

et cette fonction renvoyant un double xxx

si nous avons maintenant xxx < / pré>

bien jusqu'à présent, cependant: xxx

est un moyen de modifier ref (la façon dont vous préférez) mais pas la fonction amusante, de sorte que le dernier La ligne renvoie une erreur de compilation? Veuillez noter que vous pouvez modifier la signature du constructeur (aussi longtemps que je suis capable d'initialiser la référence comme prévu).


0 commentaires

4 Réponses :


3
votes

Non, et votre code peut être cassé même avec une référence normale. Il suffit de documenter le fait que l'objet adopté doit être persistant.

double *x = new double;
Ref<double> ref(*x);
delete x;    


2 commentaires

+1. Etat clairement dans la documentation en quoi il doit être utilisé. Mais ce n'est pas votre responsabilité de prendre en compte des abus de votre classe.


Le but de cette restriction est d'aider les utilisateurs. Comme il est assez facile d'aider les utilisateurs dans ce cas, je ne pense pas que cela soit rejeté de la main. Le rejeter en détail, en détail, s'il y a une raison pour laquelle cela n'aide pas les utilisateurs après tout ;-)



2
votes

Vous n'aimerez peut-être pas que la syntaxe l'utilise, mais faites le constructeur prendre un pointeur au lieu d'une référence. Vous ne pouvez pas prendre même un indicateur de const à un poste temporaire.

au moins, pas sans la contrebande de la contrebande à travers une autre wrapper qui, espérons-le, le code manifestement fausse (TM): Template T * REFTOPTR (T & t) {retour & t; }

qui dit, si vous utilisez ce mode référence_wrapper est utilisé, vos utilisateurs peuvent en réalité veux pour capturer des temporaires. Tant que l'objet REF est également temporaire dans la même expression complète que la capture temporaire, je pense que c'est bien. Donc, par exemple, xxx


1 commentaires

Ceci est (pour moi) le plus proche du problème indiqué (avec des considérations aussi intéressantes, notamment la dernière), merci pour votre aide!



1
votes

Utilisez un argument de pointeur pour initialiser votre membre du pointeur. N'utilisez pas de référence (const) pour cela - utilisez un pointeur pour initialiser un pointeur.

J'ai eu des problèmes de suivi des références dans le passé et, bien que ce ne soit pas directement lié à votre question, vous pourriez trouver ces deux threads intéressants:


0 commentaires

0
votes

Vous pouvez utiliser un modèle. u & code> est déduit à double et code>, et qui ne se lie pas aux rvalues.

template<class T>
class Ref {
public:
  template<typename U>
  explicit Ref(U& t, 
               typename boost::enable_if< 
                 boost::is_convertible<U, T&> 
               >::type * = 0) 
    : m_ptr(&t) {}
private:
  T* m_ptr;
};


0 commentaires