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.