web-dev-qa-db-fra.com

Comment le type de retour d'un opérateur ternaire est-il déterminé?

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>)?

32
Meraj al Maksud

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 comme std::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 comme a = (b = c), et non comme (a = b) = c En raison de l'associativité de droite à gauche de l'affectation, mais a + b - c Est analysé (a + b) - c et non a + (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 Est delete (++(*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 non a.(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.

0
Meraj al Maksud