2010-12-09 20 views
3

Je possède ce code exemple:Est-ce un code C++ valide selon la norme?

struct A 
{ 
    bool test() const 
    { 
     return false; 
    } 
}; 


template <typename T = A> 
class Test 
{ 
public: 
    Test(const T& t = T()) : t_(t){} 

    void f() 
    { 
     if(t_.test()) 
     { 
      //Do something 
     } 
    } 
private: 
    const T& t_; 
}; 

int main() 
{ 
    Test<> a; 
    a.f(); 
} 

Fondamentalement, je suis inquiet au sujet du constructeur de Test où je stocke une référence const à une variable temporaire et l'utiliser dans methof f. La référence d'objet temporaire reste-t-elle valide à l'intérieur de f?

+1

Je pense - NON. Le compilateur ne peut pas suivre (dans le cas général) l'emplacement de la référence et s'il est stocké de manière persistante. Mais le plus simple est d'écrire un exemple d'application et de voir ce qui se passe. – valdo

+0

Cela fonctionne sur VS2008, mais je ne suis pas trop convaincu de son droit. – Naveen

Répondre

7

Il ne restera pas valide. L'objet temporaire sera détruit après l'initialisation a. Au moment où vous appelez f, vous invoquez un comportement indéfini en appelant test. Seul ce qui suit est valide:

// Valid - both temporary objects are alive until after the 
// full expression has been evaluated. 
Test<>().f(); 
+0

Etes-vous sûr? 'Une liaison temporaire à un membre de référence dans le ctor-initializer d'un constructeur (12.6.2) persiste jusqu'à la sortie du constructeur. Une liaison temporaire à un paramètre de référence dans un appel de fonction (5.2.2) persiste jusqu'à la fin de l'expression complète contenant l'appel. »- ceci étant le premier cas, je ne sais pas si c'est valide ... – etarion

+0

@ etarion, 12.6.2 parle d'expressions temporaires. I.e expressions qui se réfèrent directement à un objet temporaire. Dans ce cas, nous initialisons un membre de référence par une expression qui ne se réfère pas directement à un objet temporaire, mais plutôt à une liaison de référence entre les deux. Ce n'est pas dit explicitement là-dedans, mais c'est ce que l'on veut dire. Donc, vous devez appliquer le deuxième cas. –

+0

@etarion pour rendre cela plus clair. Considérons quelques exemples: 'struct A {A & f() {return * this; }}; '. L'intention est que 'A(). F(). F()' soit valide, même si le texte dit "Une liaison temporaire à la valeur retournée dans une déclaration de retour de fonction (6.6.3) persiste jusqu'à ce que la fonction se termine. " –