Je résolvais un problème de mouvement d'un évêque sur un échiquier. À un moment de mon code, j'ai eu la déclaration suivante:
std::cout << (abs(c2-c1) == abs(r2-r1)) ? 1 : 2 << std::endl;
Cela génère l'erreur suivante:
error: invalid operands of types 'int' and '<unresolved overloaded function type>' to binary 'operator<<'
Cependant, j'ai corrigé instantanément cette erreur en incluant une variable supplémentaire dans mon code:
int steps = (abs(c2-c1) == abs(r2-r1)) ? 1 : 2;
std::cout << steps << std::endl;
Comment fonctionne l'opérateur ternaire et comment son type de retour est-il déterminé (comme le compilateur l'appelait <unresolved overloaded function type>
)?
Selon cppreference :
Lors de l'analyse d'une expression, un opérateur qui est répertorié sur une ligne du tableau ci-dessus avec une priorité sera lié plus étroitement (comme par des parenthèses) à ses arguments que tout opérateur qui est répertorié sur une ligne plus en dessous avec une priorité inférieure. Par exemple, les expressions
std::cout << a & b
Et*p++
Sont analysées comme(std::cout << a) & b
Et*(p++)
, et non commestd::cout << (a & b)
ou(*p)++
.Les opérateurs qui ont la même priorité sont liés à leurs arguments dans le sens de leur associativité. Par exemple, l'expression
a = b = c
Est analysée commea = (b = c)
, et non comme(a = b) = c
En raison de l'associativité de droite à gauche de l'affectation, maisa + b - c
Est analysé(a + b) - c
et nona + (b - c)
en raison de l'associativité de gauche à droite de l'addition et de la soustraction.La spécificité d'associativité est redondante pour les opérateurs unaires et n'est présentée que pour être complète: les opérateurs de préfixe unaires associent toujours de droite à gauche (
delete ++*p
Estdelete (++(*p)))
et les opérateurs de suffixe unaires associent toujours de gauche à droite (a[1][2]++
Est((a[1])[2])++
). Notez que l'associativité est significative pour les opérateurs d'accès membres, même s'ils sont regroupés avec des opérateurs de suffixe unaires:a.b++
Est analysé(a.b)++
et nona.(b++)
.La priorité de l'opérateur n'est pas affectée par la surcharge de l'opérateur. Par exemple,
std::cout << a ? b : c;
Est analysé comme(std::cout << a) ? b : c;
Car la priorité du décalage arithmétique vers la gauche est plus élevée que l'opérateur conditionnel.