web-dev-qa-db-fra.com

"Instanciation implicite d'un modèle non défini" lors de la déclaration de classe de modèle

J'ai un code dans lequel j'ai besoin de déclarer en avant la classe de modèle (ou au moins, une déclaration en aval me faciliterait grandement les choses ...). J'ai écrit une version simplifiée du problème que je rencontre afin de pouvoir l'afficher ici:

template<bool>
class MyTemplateClass;

int main( int argc, char* argv[] )
{
    MyTemplateClass<false> myTemp;  // error here
    myTemp.GetTheValue();
    return 0;
}

template<bool bShouldMult>
class MyTemplateClass
{
    int m_myint;
    float m_myfloat;

public:
    MyTemplateClass() : m_myint(5), m_myfloat(3.0f) {}
    float GetTheValue()
    {
        return m_myint * (bShouldMult ? m_myfloat : 1.0f);
    }   

};

L'erreur que je reçois à la ligne commentée est:

Error - implicit instantiation of undefined template 'MyTemplateClass<false>'

Quels autres détails dois-je inclure dans une déclaration avancée de MyTemplateClass? Puisque l'erreur ne vient pas de la ligne suivante, je suppose que ce n'est pas dû au fait que la méthode est indéfinie. Le compilateur que j'utilise est LLVM/CLang et je compile sur Mac.

24
benwad

Afin de déclarer une variable de tout type, modèle ou non, la définition complète de ce type doit être disponible. Vous ne pouvez pas déclarer un modèle par la suite, puis commencer à l'utiliser comme s'il était défini. Tout ce que vous pouvez faire à ce stade est de déclarer un pointeur sur un objet d'un type basé sur le modèle, comme ceci:

MyTemplateClass<false> *myTempPtr;  // No error here

Malheureusement (mais pas de manière inattendue) cela déplace l'erreur à la ligne suivante. Le problème d'initialisation de ce pointeur persiste: une fois que vous tentez d'appeler new MyTemplateClass<false>, vous verrez une erreur.

Vous devez réorganiser votre code pour déplacer la définition du modèle avant son lieu d'utilisation. Cela peut sembler fastidieux, mais il n’ya pas de solution: le compilateur doit avoir la définition complète au moment où vous commencez à instancier votre modèle et à appeler ses méthodes.

21
dasblinkenlight

Avez-vous oublié de #include quelque chose?

Je l'ai eu après avoir oublié de 

#include <array>

Lorsque vous utilisez un std::array

: ^)

49
kmiklas

C'est de ma compréhension que vous ne pouvez pas transmettre quelque chose et l'instancier ensuite dans votre pile (modèle ou pas).

De plus, je ne pense pas qu'il existe un très large soutien pour la définition en aval de la classe de modèle

0
Arthur