2013-04-08 3 views
1

J'ai un objet comme ce qui suitModèle version d'exécution différent de débogage

template<typename T> 
inline void UnusedParameter(T const&) 
{ 

} 

class Client 
{ 
public: 
    template<class T> 
    void runFFT(T *wSamples, float const &fMult) 
    { 
    std::cout << "INSIDE RUNFFT : : :" << std::endl; 
    UnusedParameter(wSamples); 
    UnusedParameter(fMult); 
    } 
}; 

Et dans mon RPC, je donne les résultats suivants:

#include "object.hpp" 

template<> 
void Client::runFFT<int16_t>(int16_t *wSamples, float const &fMult) 
{ 
    std::cout << "INSIDE INT16_T version: : :" << std::endl; 
    UnusedParameter(wSamples); 
    UnusedParameter(fMult); 
} 

template<> 
void Client::runFFT<Ipp32f>(Ipp32f *wSamples, float const &fMult) 
{ 
    std::cout << "INSIDE IPP32F version: : :" << std::endl; 
    UnusedParameter(wSamples); 
    UnusedParameter(fMult); 
} 

Ces deux parcours de mise en œuvre sans aucun problème dans mon code de débogage . Il entre dans la version int16_t sans problème et la version Ipp32f aussi sans problème. Mais quand j'essaie la version Run, elle ne fait que entrer dans le Template, comme le compilateur compile uniquement l'implémentation du Template dans l'en-tête.

Comment puis-je éviter que cela n'arrive? Dois-je supprimer cela et juste créer deux méthodes différentes? J'adore mes modèles mais ces bogues de Heisenberg sont trépidants.

Merci pour toute contribution.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

Andy Prowl a répondu à cette question et il est résolu faire ce qui suit dans l'HPP:

template<typename T> 
inline void UnusedParameter(T const&) 
{ 

} 

class Client 
{ 
public: 
    template<class T> 
    void runFFT(T *, float const &) 
    { 
    // Thanks for Joachim for removing my Unused Parameter crap 
    std::cout << "INSIDE RUNFFT : : :" << std::endl; 
    } 
}; 

template<> 
void Client::runFFT<int16_t>(int16_t *wSamples, float const &fMult); 

template<> 
void Client::runFFT<Ipp32f>(Ipp32f *wSamples, float const &fMult); 

Et maintenant, il travaille dans l'exécution aussi bien. Le RPC reste le même.

+2

Un petit conseil: Si vous ne voulez pas les avertissements "argument non utilisé", déclarez simplement le type mais pas le nom. Comme 'void runFFT (T *, float const &)' –

+0

'AnalyzerClient' est-il une sous-classe de' Client'? –

+1

En ce qui concerne votre problème, un débogueur efface normalement toutes les variables, même les variables locales. Cela signifie que vous pourriez avoir une vérification 'NULL' qui réussit dans le débogueur mais échoue lorsque vous ne courez pas dans le débogueur. Pour résoudre ce problème, assurez-vous d'initialiser correctement toutes les variables, par exemple en réglant les pointeurs sur '0' (ou' NULL' ou 'nullptr'). –

Répondre

3

Le problème est très probablement dans le fait que vous relégués les spécialisations de votre fonction membre runFFT() pour int16_t et Ipp32f dans un fichier .cpp séparé sans fournir une déclaration correspondante après le modèle primaire, de sorte que le compilateur au point de instanciation (qui appartient probablement à une autre unité de traduction que #include s seul le fichier d'en-tête contenant la définition de Client) ne connaît pas l'existence de ces spécialisations explicites.

Mettez une déclaration pour les spécialisations dans le même fichier d'en-tête qui contient la définition de votre modèle de classe:

template<typename T> 
inline void UnusedParameter(T const&) { } 

class Client 
{ 
public: 
    template<class T> 
    void runFFT(T *wSamples, float const &fMult) 
    { 
     std::cout << "INSIDE RUNFFT : : :" << std::endl; 
     UnusedParameter(wSamples); 
     UnusedParameter(fMult); 
    } 
}; 

// DECLARE YOUR EXPLICIT SPECIALIZATIONS HERE 

template<> 
void Client::runFFT<int16_t>(int16_t *wSamples, float const &fMult); 

template<> 
void Client::runFFT<Ipp32f>(Ipp32f *wSamples, float const &fMult); 

par paragraphe 14.7.3/6 du 11 C++ Standard:

Si un modèle, un modèle de membre ou d'un membre d'un modèle de classe est alors explicitement spécialisée que la spécialisation doit être décembre avant la première utilisation de cette spécialisation qui provoquerait une instanciation implicite avoir lieu, dans chaque unité de traduction dans laquelle une telle utilisation se produit; aucun diagnostic n'est requis. [...]

Le « pas de diagnostic est nécessaire » partie signifie que si vous ne suivez pas cette règle, votre programme sera mal formé, mais n'est pas nécessaire que votre compilateur/éditeur de liens pour dire toi. Cela entraîne normalement le type de comportement non défini que vous observez.

+0

Non, cela donnera une "définition multiple de' void Client :: runFFT (float *, float const &) "erreur. Les spécialisations de modèle vont dans le fichier CPP. Compilé avec GCC 4.3.3 – Claudiordgz

+1

@Claudiordgz: Correct, désolé. Je voulais écrire "mettre une déclaration pour ces spécialisations". Si vous ne faites pas cela, le compilateur ne sera pas au courant de leur existence –

+0

Vous êtes génial Andry Prowl. Merci beaucoup. – Claudiordgz

Questions connexes