2010-05-19 5 views
2

suite de morceau de code ne compile pas, le problème est dans T::rank pas être inaccessible (je pense) ou non initialisé dans le modèle parent.C++ CRTP (modèle de modèle) question

Pouvez-vous me dire exactement quel est le problème? passe le rang explicitement le seul moyen? ou existe-t-il un moyen d'interroger la classe tensorielle directement?

Merci

#include <boost/utility/enable_if.hpp> 

template<class T, // size_t N, 
     class enable = void> 
struct tensor_operator; 

// template<class T, size_t N> 
template<class T> 
struct tensor_operator<T, typename boost::enable_if_c< T::rank == 4>::type > { 
    tensor_operator(T &tensor) : tensor_(tensor) {} 
    T& operator()(int i,int j,int k,int l) { 
     return tensor_.layout.element_at(i, j, k, l); 
    } 
    T &tensor_; 
}; 

template<size_t N, typename T = double> 
// struct tensor : tensor_operator<tensor<N,T>, N> { 
struct tensor : tensor_operator<tensor<N,T> > { 
    static const size_t rank = N; 
}; 

tensor <4> D; // compiler attempts to instantiate undefined template, not specialization 

Je sais que la solution de contournement, mais suis intéressé par la mécanique du modèle instanciation pour l'auto-éducation

+0

Pourrait-il être lié à ce bug que j'ai trouvé dans Visual Studio? http://connect.microsoft.com/VisualStudio/feedback/details/354162/seemingly-valid-dependant-types-in-nested-template-not-accepted –

+0

@kirill g ++ 4.3. J'ai oublié d'ajouter la dernière ligne avec l'instanciation, corrigé maintenant – Anycorn

+0

@evan ça ressemble effectivement à – Anycorn

Répondre

2

En CRTP la classe de base modèle tire parti du fait que les corps de fonctions membres (définitions) ne sont instanciés que longtemps après leurs déclarations. Dans votre code, la classe de base dépend du type incomplet.

+0

Cette réponse est en effet correcte. Cela provoque un échec SFINAE pour 'T :: rank' (parce que le membre' :: rank' n'a pas encore été déclaré) parce que le point d'instanciation est avant le point d'instanciation de 'tensor <4>'. Voir http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#287 pour un aperçu des problèmes connexes. –

2

Suis-je le seul regardant une récursion infinie ici?

  • tensor<N,T> dépend de tensor_operator< tensor<N,T> >
  • tensor_operator< tensor<N,T> > dépend de tensor<N,T>

Je ne me souviens pas d'une situation où je une propriété de classe Derived de décider si oui ou non à instancier Base, mais il ne semble Pour moi, cela provoquerait une récurrence infinie.

Voici l'erreur sur gcc 3.4.2:

In instantiation of `tensor<4ul, double>': 
41: instantiated from here 
33: error: invalid use of undefined type 
          `struct tensor_operator<tensor<4ul, double>, void>' 
19: error: declaration of `struct tensor_operator<tensor<4ul, double>, void>' 

La question semble être ici que l'instanciation de tensor_operator<N,T> dépend de l'instanciation de tensor_operator<N,T> ...

+1

Je ne pense pas que ce soit un problème de récursivité. Je pense que peut-être parce que rank est spécifié après que le modèle parent est instancié, il n'est tout simplement pas là? – Anycorn