2010-12-04 35 views
5

J'essaie de surcharger l'opérateur ostream pour autoriser la sortie d'une classe imbriquée dans un modèle. Cependant, le compilateur est incapable de lier l'appel de fonction réel à ma surcharge.Sortie d'une classe imbriquée dans un modèle

template <class T> 
struct foo 
{ 
    struct bar { }; 
}; 

template <class T> 
std::ostream& operator << (std::ostream& os, 
    const typename foo<T>::bar& b) 
{ 
    return os; 
} 

int main() 
{ 
    foo<int>::bar b; 
    std::cout << b << std::endl; // fails to compile 
} 

Cela compilera si je la surcharge en définir une fonction en ligne friend:

template <class T> 
struct foo 
{ 
    struct bar 
    { 
     friend std::ostream& operator << (std::ostream& os, const bar& b) 
     { 
      return os; 
     } 
    }; 
}; 

Mais je préfère définir la surcharge en dehors de la classe. Est-ce possible?

+1

Voir http://stackoverflow.com/questions/4092237/c-nested-class-of-a-template-class –

Répondre

1

No. :-) Vous avez déjà répondu à votre propre question, mais vous n'aimez pas la réponse? Johannes renvoie à un article qui explique que la classe interne est un «contexte non déduit». S'il y a des spécialisations du modèle foo, il peut y avoir plusieurs foos avec la même classe de barre interne. Le compilateur ne peut alors pas comprendre ce que foo :: bar est, sauf s'il instancie foo pour tous les Ts possibles. La norme dit que ce n'est pas nécessaire.

Quel est le problème avec votre solution d'origine avec un opérateur ami? Vous n'avez pas à le définir en ligne, il suffit de le déclarer dans la classe locale.