- Sur les conditions de convergence en termes de 24-: https://blog.csdn.net/qq_41453285/article/details/104311944
Un exemple d'erreur de modèle de fonction non-membre
-
Nous avons dit en termes de 24, pour la classe rationnelle, afin de faire toutes les opérations de multiplication sont accessibles par l'opération, en tant que version de fonction non-membre , nous serons en fonction de l' opérateur * () est défini (les détails peuvent revenir pour voir). Mais pour le modèle, ces règles ne peuvent pas tenir
- Par exemple nous allons mettre la fonction * rationnelle et l' opérateur () est défini comme un modèle de code est suit comme:
//下面与条款24都相同,只是改为了模板
template<typename T>
class Rational {
public:
Rational(const T& numerator = 0, const T& denominator = 1);
const T numerator()const;
const T denominator()const;
};
template<typename T>
const Rational<T> operator*(const Rational<T>& lhs, const Rational<T>& rhs)
{
}
- Maintenant , nous écrivons le code suivant ne peut pas compiler. Par exemple:
Rational<int> oneHalf(1, 2);
//在条款24中,Rational和operator*为非模板,此处代码可编译通过
//此处,Rational和operator*为模板,编译不通过
Rational<int> result = oneHalf * 2;
Analyse d'erreur
- La raison de cette erreur est: au- dessusfonction « OneHalf * 2 » Aucun opérateur de correspondance * (),entraîne une erreur
- raison:
- OneHalf de type de Rational <int>, il correspond au modèle de fonction * opérateur (), et le modèle de fonction * opérateur () instance de modèle type T en int
- Cependant, lorsque le second paramètre de fonctionnement, lorsque deux int, la fonction opérateur * () est un modèle ne peut pas être déduite à partir d'un type int T
- Ainsi, le compilateur finale ne peut pas trouver une fonction * opérateur approprié () et conduire à des erreurs
- Dans l'opérateur non-modèle * () à, opérateur * () 2 peut être une conversion implicite (conversion implicite rationnelle fournit les détails, puis passer àarticle 24) commeobjets Rational. Mais dans le modèle, la conversion implicite n'est pas autorisé
- prises pour tirer l'argument du modèle facteur décisif
D'autre part, la fonction de modèle déclaré comme ami
- Dans la « une », la classe de modèle et fonctions de modèle que nous utilisons le mauvais, une solution est à l'opérateur () * déclarée en tant que classes d'ami de modèle Rational (ami)
- Let a été de modifier deux fois, et, finalement, le mauvais code
La première modification (compilateur, mais mauvais lien)
- Nous avons d' abord l' opérateur () * Déclaré comme ami rationnelle . Code est la suivante:
template<typename T> class Rational { public: //友元,函数声明 friend const Rational operator*(const Rational& lhs, const Rational& rhs); }; //函数定义 template<typename T> const Rational<T> operator*(const Rational<T>& lhs, const Rational<T>& rhs); int main() { Rational<int> oneHalf(1, 2); //编译通过,但是链接时出错 Rational<int> result = oneHalf * 2; return 0; }
- Note: Le plus haut ami dansvie, nous n'ajoutons pas dans le dos rationnel <T>, qui rationnel <T> est le même,deux sont
- Compilé en raison de:
- OneHalf lorsque l'objet est défini, le programme va générer un rationnel <int> classe définie, puis la classe rationnelle <int> est instancié sur
- classe rationnelle <int> Après avoir été instancié, la fonction opérateur ami * () sont automatiquement déclarés hors (Note: ne déclarée mais non définie)
- Une fois la fonction opérateur ami * () est déclaré hors, la fonction est une fonction, plutôt que d'un modèle, afin que nous puissions transmettre à la fonction 2 (2 implicitement et la conversion de type de paramètre, sera converti en 2 rationnelle)
- Ainsi, le code ci-dessus sur elle par le compilateur, mais des erreurs lien (ci-dessous)
- La raison du lien d'erreur:
- Parce que la déclaration classe rationnelle <int> est instancié est sorti, ami vient de l'opérateur * (), mais ne se définit pas, donc l'erreur de programme
Le deuxième amendement (version correcte)
- La compilation de code ci-dessus, mais le lien à travers, étant donné que la définition n'a pas pu trouver l'opérateur * () de
- méthode d'erreur Lien à résoudre est: En même temps, la définition de cette fonction dans une fonction ami déclaration. Code est la suivante:
template<typename T> class Rational { public: //声明的时候,同时实现该函数(备注,该函数虽然在类中定义,但不属于成员函数) friend const Rational operator*(const Rational& lhs, const Rational& rhs) { return Rational(lhs.numerator()*rhs.numerator(), lhs.denominator()*lhs.denominator()); } };
- Un autre avantage de l'ami ici: Bien que cette fonction nous déclarons ami, mais n'a pas eu accès à une catégorie de membres non publiques, de façon relativement sûre
Troisièmement, faire des appels de fonctions d'aide d'ami (lié à la ligne)
- Nous avons dit que , en termes de 30, si la fonction est définie dans la classe deviendra en ligne, et donc ce qui précède , nous définir opérateur ami dans la classe de () * sera appelée ligne
- Afin de minimiser l'impact de la ligne apporte, nous pouvons:
- Nous ne pouvons pas faire () * dans quel opérateur, sera la chose complète à une autre fonction auxiliaire
- L'aide devrait être un modèle
-
Code est la suivante:
-
Pouropérateur de faire * () optimiséligne dans la classe, on définit une fonction d'assistance, dans laquelle l'opérateur complet * () est censé remplir la fonction
-
doMultiply () ne prend pas en charge le fonctionnement hybride (comme un objet et un int multiplication Rational), mais la fonction * () est appelée uniquement par l'opérateur, et l'opérateur * () supporte l'opération de mélange, et donc fonctionnel
-
//声明
template<typename T> class Rational
//函数声明(定义在下)
template<typename T>
const Rational<T> doMultiply(const Rational<T>& lhs, const Rational<T>& rhs);
template<typename T>
class Rational {
public:
friend
const Rational operator*(const Rational& lhs, const Rational& rhs)
{
//在其中调用doMultiply(),可使inline最优化
return doMultiply(lhs, rhs);
}
};
//完成原本operator*()要完成的功能
template<typename T>
const Rational<T> doMultiply(const Rational<T>& lhs, const Rational<T>& rhs)
{
return Rational<T>(lhs.numerator()*rhs.numerator(),
lhs.denominator()*lhs.denominator());
}
IV Résumé
- Lorsque nous écrivons un modèle de classe, et il fournit le « modèle associé à ce » soutien « de la fonction de tous les paramètres de la conversion de type implicite », définissez les fonctions définies comme « à l'intérieur du modèle de classe fonction ami »