Explicite de spécialisation après l'instanciation
J'ai le code suivant:
typedef vector<int> Vec;
typedef vector<Vec> VecOfVec;
template<typename Vec>
Vec DoSomething(const Vec &v);
template<>
VecOfVec DoSomething<VecOfVec>(const VecOfVec &v)
{
VecOfVec r;
for(auto i = v.begin(); i != v.end(); i++)
r.push_back(DoSomething(*i));
return r;
}
template<>
Vec DoSomething<Vec>(const Vec &v) //Error here
{
return v; //for the sake of the example
}
J'obtiens l'erreur suivante:
explicit specialization of 'DoSomething<vector<int> >' after instantiation
à la ligne marquée.
Le compilateur insiste sur le fait qu'il a déjà instancié DoSomething<vector<int> >
, alors qu'il ne peut pas, et un programme simple peut le prouver:
typedef vector<int> Vec;
typedef vector<Vec> VecOfVec;
template<typename Vec>
Vec DoSomething(const Vec &v);
template<>
VecOfVec DoSomething<VecOfVec>(const VecOfVec &v)
{
VecOfVec r;
for(auto i = v.begin(); i != v.end(); i++)
r.push_back(DoSomething(*i));
return r;
}
Résultats en externe non résolu.
Pourquoi le compilateur en disant que c'est déjà instancié quand elle ne peut pas et ne même pas? et pourquoi ne pas le compilateur de traiter comme symbole non résolu, alors que l'éditeur de liens n'?
Je sais que la commutation de la méthode afin de la résoudre, mais je veux savoir pourquoi le compilateur de le faire.
OriginalL'auteur Dani | 2011-10-14
Vous devez vous connecter pour publier un commentaire.
Le code demandé une instanciation implicite à
DoSomething(*i)
. Le fait que vous n'avez pas de définir le modèle en ce que l'unité de traduction signifie qu'il ne peut pas instancier une spécialisation, d'oùDoSomething(*i)
donne un "symbole non résolu" (liens) erreur dans votre cas. Pour se débarrasser de cette erreur, vous devez définir le modèle en que TU, ou de fournir une instanciation explicite directive de ce modèle dans un TU qui permet de définir le modèle.Le simple fait que le code demande implicite de l'instanciation de la spécialisation
DoSomething<vector<int> >
avant de vous explicitement prévu que la spécialisation est assez pour que le programme devienne mal formé (sans qu'un diagnostic soit nécessaire; le compilateur fait un bon travail ici, il n'est pas nécessaire de le faire).@CharlesBailey utilement notes, la déclaration explicite de spécialisation est tout à fait suffisante; une définition de celui-ci peut être dispensée par ailleurs, même en dehors de l'aide des touches TU.
Je pense que la partie "le simple fait que Le code demande implicite de l'instanciation de la spécialisation
DoSomething<vector<int> >
avant de vous explicitement prévu que la spécialisation est assez pour que le programme devienne mal formé" n'est pas correct, ou il y a quelque chose qui manque dans elle. Il devrait plutôt être : le simple fait que Le code demande implicite de l'instanciation de la spécialisationDoSomething<vector<int> >
à partir d'un plein de spécialisation avant de vous explicitement prévu que la spécialisation est assez pour que le programme devienne mal formé. Corrigez-moi si je me trompe. 🙂si vous à la fois dire que l'implicite est différent de l'explicite à un niveau qu'ils ne peuvent pas être échangés?
Vous avez seulement besoin de déclarer explicite de spécialisation en avant un code qui cause implicite de l'instanciation de la spécialisation. La définition peut être ailleurs.
Ce que j'ai écrit est la cause d'une instanciation implicite. Vous obtenez un mal formé (NDR) programme, même lorsque vous cause implicite de l'instanciation de l'intérieur d'un modèle de fonction:
template<typename T> void f() { DoSomething<vector<int> >(vector<int>()); }
avant de fournir de manière explicite de la spécialisation.OriginalL'auteur Johannes Schaub - litb
En général, il signifie simplement que vous n'avez pas à fournir un "prototype" pour le modèle de la spécialisation. En d'autres termes, vous n'avez pas donner le compilateur une tête que "hé, il va y avoir une spécialisation spécifique pour ce type de la fonction, afin de ne pas brancher le mauvais."
Dans mon cas, j'ai eu un modèle de spécialisation dans un
.cpp
fichier, et j'ai obtenu cette erreur. En fournissant un "prototype de fonction" (qui est juste le modèle de spécialisation en-tête suivi par un point-virgule, comme un prototype de fonction) a résolu le problème.OriginalL'auteur bobobobo