3 votes

Pourquoi le code suivant avec une fonction de conversion non-const n'est-il pas ambigu ?

Considérons le code suivant (tiré de https://en.cppreference.com/w/cpp/language/cast_operator )

struct To {
    To() = default;
    To(const struct From&) {} // converting constructor
};

struct From {
    operator To() const {return To();} // conversion function
};

int main()
{
    From f;

    To t2 = f; // copy-initialization: ambiguous
// (note, if conversion function is from a non-const type, e.g.
//  From::operator To();, it will be selected instead of the ctor in this case)
}

Comme le disent les commentaires, la ligne suivante est en effet ambiguë car il y a deux candidats (La fonction de conversion et le constructeur de conversion sont également applicables)

To t2 = f; //compile error

Cependant, comme le dit la note, si je supprime l'option const del conversion ce qui donne le code suivant :

struct From {
    operator To() {return To();} // conversion function
};

L'appel compile bien.
Le site const ne doit pas affecter l'attribut conversion la valeur de retour de la fonction, alors pourquoi l'appel n'est plus ambigu ?

3voto

StoryTeller Points 6139

Le qualificatif const ne devrait pas affecter la valeur de retour de la fonction de conversion, alors pourquoi l'appel n'est plus ambigu ?

Cela n'affecte pas le résultat, mais cela affecte la résolution de la surcharge pour choisir la meilleure méthode viable. C'est similaire au cas de ces fonctions inventées

To make(From const&);
To make(From&);

Quelle surcharge correspond le mieux à make(f) ? C'est la seconde, car le type du paramètre, étant non-const, correspond mieux à l'argument ( f ), qui est lui-même non-const.

1voto

user2079303 Points 4916

Le qualificatif const ne doit pas affecter la valeur de retour de la fonction de conversion.

Cela ne l'affecte pas en effet, mais ce n'est pas non plus pertinent.

Ce qu'il affecte est l'argument - qui est la référence implicite à this . L'argument implicite est une lvalue const pour les fonctions membres const et non-const pour les fonctions membres non-const. Les arguments sont ce qui affecte la résolution de la surcharge.

Dans le code original, les arguments du constructeur et de l'opérateur de conversion sont exactement les mêmes, donc une séquence de conversion de n'importe quel type vers l'un ou l'autre argument est également préférable, et donc ambiguë.

Sans le const, votre expression non-const de valeur l f ne nécessite aucune conversion, alors que le constructeur nécessite une conversion en const lvalue. En tant que tel, l'opérateur est préféré par la résolution de surcharge. Si vous aviez écrit const From f; alors le constructeur dont l'argument est const aurait été choisi à la place car dans ce cas, l'opérateur de conversion non const ne serait même pas un candidat valide.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X