2017-04-10 2 views
3

Je possède ce code:Pourquoi les modèles déclarés dans la structure sur l'en-tête ne violent-ils pas ODR et la spécialisation?

#include <iostream> 

struct A 
{ 
    template<typename T> bool isImplemented() 
    { 
       std::cout << "Not Implemented" << std::endl; 
       return false; 
    } 
}; 

template<> inline bool A::isImplemented<int>() 
{ 
    std::cout << "int Implemented" << std::endl; 
    return true; 
} 

Je peux comprendre pourquoi la spécialisation du modèle a besoin de la ligne, afin d'éviter l'ODR être violé la ligne va fusionner la table de traduction éviter un conflit.

Mais, pourquoi je n'ai pas besoin d'un inline sur le isImplemented à l'intérieur de la structure A? Peut-être que cette question peut être étendue à, pourquoi si la méthode est déclarée dans la structure/classe sur l'en-tête, il n'a pas besoin de l'inline? Comme je peux le comprendre, il créerait les symboles sur chaque fichier objet (.o) qu'il est appelé, en violation de l'ODR, pourquoi cela ne se produit pas?

+3

Quelque chose avec un paramètre de modèle est essentiellement implicitement 'inline'. – aschepler

+2

La spécialisation de modèle est une fonction. Le modèle est un modèle. Les modèles ne sont pas des fonctions, et vice versa. Les modèles suivent des règles différentes. –

+0

@KerrekSB qui aide réellement beaucoup, merci. J'avais des problèmes en essayant de comprendre pourquoi je n'avais besoin que de spécialisations. J'imagine que c'est la même règle appliquée lorsque vous déclarez des opérateurs amis et vous devez utiliser en ligne afin d'empêcher la violation sur l'ODR, non? – Lefsler

Répondre

3

Vous n'avez pas besoin pour deux raisons:

  • Chaque fonction définie dans la définition de la classe est implicite inline. Un modèle n'a pas besoin de mot-clé inline. Rappelez-vous, votre fonction d'origine est un modèle, tandis que la spécialisation ne l'est pas.
1

Le point à souligner ici est que template<typename T> bool isImplemented()est pas une fonction. Il s'agit d'un modèle pour une fonction et n'existera (en tant que code) qu'une fois spécialisé, comme vous l'avez fait avec template<> inline bool A::isImplemented<int>(). Le inline n'est pas obligatoire ici. Programme compile et fonctionne parfaitement sans elle.

Etrangement votre struct A ne dépend pas de n'importe quel paramètre de modèle ni de la méthode isImplemented() donc j'essaie toujours de comprendre votre intention.

Une simple utilisation de vos fonctions pourrait ressembler à ceci:

int main() 
{ 
    A a; 

    a.isImplemented<int>(); 
    a.isImplemented<double>(); 
} 

Et la sortie:

int Implemented 
Not Implemented 

Et vous êtes essentiellement en mesure de dire spécialisations Wich vous avez explicitement mis en œuvre des génériques . Est-ce ce dont vous avez besoin?

EDIT:

Donné le commentaire sur ma réponse, je crois que la question initiale est bien répondu ici:

+0

En fait, c'est un code que j'ai écrit pour comprendre l'inline et l'ODR. C'est pourquoi c'est comme ça. Cela vient d'un problème que j'avais depuis longtemps essayé de spécialiser quelque chose en fonction du type de retour. – Lefsler