6
votes

Mauvais prototype de fonction utilisé par compilateur?

J'ai fait face à un problème de compilation que je ne comprends pas, je l'ai simplifié un peu pour expliquer ci-dessous.

Fondamentalement, il implique de disposer de 2 getters différents (un const et non) qui renvoie un conteneur (un Carte dans cet exemple) avec const, respectivement non-const value_type_type. p>

Qu'est-ce qui me casse-t-on dans l'exemple ci-dessous, le compilateur semble impossible d'utiliser le const getter sur un objet non constitué: P >

1>c:\test.cpp(48): error C2440: 'initializing' : cannot convert from 'std::map<_Kty,_Ty>' to 'std::map<_Kty,_Ty>'
1>          with
1>          [
1>              _Kty=unsigned int,
1>              _Ty=TestObjectPair
1>          ]
1>          and
1>          [
1>              _Kty=unsigned int,
1>              _Ty=ConstTestObjectPair
1>          ]
1>          No constructor could take the source type, or constructor overload resolution was ambiguous


1 commentaires

FWIW GCC se plaint au même point que: Aucune conversion viable de la "carte <[...], paire > 'to'" [...] ", paire > '


4 Réponses :


4
votes

Qu'est-ce qui me casse-t-on dans l'exemple ci-dessous, le compilateur semble incapable d'utiliser le const getter sur un objet non-Const

Ce n'est pas "incapable" mais requis pour choisir l'autre.

La surcharge est sélectionnée à l'aide des paramètres réels passés. Pour la fonction de membre, y compris le param param utilisé pour ceci . Pour t * La surcharge non-const est sélectionnée, si vous voulez que l'autre, vous devez utiliser un const T * par moulage ou d'autres moyens.

En réalité, il s'agit d'une erreur commune de penser que le type de retour sera utilisé d'une manière et d'une fonction qui renvoie ce que vous souhaitez utiliser dans l'expression est sélectionné. Ce n'est tout simplement pas le cas.


0 commentaires

5
votes

Si vous êtes vraiment curieux, consultez la section 13.3.3 de la norme C ++ 03, qui décrit la manière dont la "meilleure fonction viable" est déterminée. Voici quelques points importants:

Les critères de sélection de la meilleure fonction sont le nombre d'arguments, comment les arguments Faites correspondre les types des paramètres de la fonction candidat, comment bien (pour les fonctions des membres non artistiques) L'objet correspond au paramètre d'objet implicite et à certaines autres propriétés de la fonction candidate. [Noter: La fonction sélectionnée par résolution de surcharge n'est pas garantie pour être appropriée pour le contexte. Autre Les restrictions, telles que l'accessibilité de la fonction, peuvent faire son utilisation dans le contexte appelant mal formé. ]

et plus tard:

S'il y a exactement une fonction viable qui constitue une meilleure fonction que toutes les autres fonctions viables, c'est le un sélectionné par résolution de surcharge

Notez que le type de retour de la fonction n'est pas mentionné dans ce critère. La méthode de non-const est donc sélectionnée comme la plus valide, car son "paramètre d'objet implicite" (essentiellement le "Ce" pointeur ") est non constitué. Tout cela se passe avant que le conflit avec le type de retour est détecté.

Pour résoudre ce problème, je voudrais soit:

  • Changez votre conception de sorte que constestestobjectpair n'est pas nécessaire et vous pouvez simplement utiliser const testobjectpair (solution préférée)
  • jeter vos objets non-consons à Const ceux en cas de besoin

3 commentaires

Merci pour le pointeur de la norme C ++, j'ai choisi cette réponse, car il s'agissait des suggestions les plus complètes et avaient des suggestions de solution.


@Duduche malheureusement, cette réponse est fausse. La méthode non-const est appelée. Et pourquoi est la citation ci-dessus de la norme cruciale? Quelle méthode attendez-vous que le compilateur appelle sinon le meilleur match? Le point crucial est, comment déterminer la meilleure fonction viable.


Oh c'était juste une faute de frappe, réparer. Et j'ai ajouté une autre citation qui devrait le rendre plus clair.



0
votes

Compiler C ++ choisira la méthode ultérieure explicite. Voici donc que PTEST est un non-const viable et pccontstest est en const un. xxx

pTest-> getObject choisira le non-const getObject: xxx

pccontstest-> getObject () choisira le const getObject: xxx

La première erreur s'est produite lorsque vous attribuez un retourné xxx

à un xxx


0 commentaires

1
votes

Le problème est assez simple. PTEST est un pointeur sur un objet de type Test , qui est pas Const . Par conséquent, dans l'appel pTest-> getObject () la fonction membre non-const est sélectionné, c'est-à-dire xxx

comme vous le voyez, cette fonction renvoie une valeur de type std :: map . Mais alors vous essayez d'initialiser la variable cto de type xxx

avec cette valeur. Pour ce faire, le compilateur doit convertir la valeur renvoyée à ce type. Mais il n'y a pas de constructeur de conversion pour le faire. Et c'est ce que l'erreur du compilateur vous dit.


0 commentaires