Modèle d’opérateur de conversion défini par l’utilisateur et opérateurs intégrés: aucune correspondance pour l’opérateur

Considérez le MCVE suivant.

#include  struct A { template<typename T, typename std::enable_if<std::is_same::value,int>::type = 0> operator T() const { return static_cast(1); } }; int main() { int x = 1; A a; return x + a; } 

Clang le comstack bien. DEMO

Mais GCC échoue avec:

 error: no match for 'operator+' (operand types are 'int' and 'A') return x + a; ~~^~~ 

Question: qui a raison et pourquoi?

Je crois que Clang a raison.

Pour effectuer une recherche sur + , puisqu’au moins un argument a un type de classe, nous considérons les candidats membres, non membres et intégrés . Il n’y a aucun candidat membre ou non-membre, donc c’est assez rapide. Il existe un candidat intégré pour int operator+(int, int) , qui est le seul candidat. Ce candidat est viable car A peut être converti directement en int (nous avons une conversion standard de A en const A& pour le paramètre d’object implicite, puis la conversion définie par l’utilisateur de celui en int , aucune conversion supplémentaire n’est nécessaire). Comme nous avons un candidat viable, cela en fait sortingvialement le meilleur candidat viable.


Notez que si A vient d’avoir l’ operator int() const { return 1; } operator int() const { return 1; } , gcc l’accepterait. Ce n’est que le modèle de fonction de conversion qui n’est pas pris en compte.