11
votes

Différentes significations des parenthèses en C ++?

Je suis un peu confus avec l'interprétation des parenthèses par le compilateur. Quelqu'un peut-il expliquer ce qui se passe réellement dans de tels contextes?

Casting: (int) a code> ou int (a) code> p>

paramètre passage: P>

template <typename t>
int size(t (&)[n]){return n;}


2 commentaires

Supports d'angle << / code> et > ne sont pas des parenthèses.


Vrai. Je ne parle pas d'eux comme des parenthèses ici. Merci pour la modification.


3 Réponses :


5
votes

casting (int) a ou int (a)

(int) a est un casting

int (a) est la construction d'un int, passant dans A à l'AT CORT

Les expressions sont évaluées en fonction de la priorité des opérateurs, de l'ARITY et de déterminer si l'opérateur a raison ou de rester associatif. Lisez le tableau précédent de la précédence dans votre texte C ++.

Obtenez une copie du programme C ++ Decl; Il lit les expressions C ++ et génère une explication de langues anglaise de l'expression. ou lisez cette explication.


2 commentaires

C'est vrai. Mais cela ne s'applique pas au deuxième cas. Comment le compilateur interpréte-t-il dans ce cas? THX


Aussi CDECL.ORG est utile mais ne prend pas en charge complètement C ++. (En tant que test, il a décrit une référence correctement, mais a déclaré que cela n'est pas pris en charge en C).



25
votes

capitaine pédantique à la rescousse!

Si vous écrivez xxx

C'est ce que l'on appelle comme une conversion de type et est régie par §5.2.3. Le libellé exact dit que

Un spécificateur de type simple (7.1.5) suivi d'une liste d'expression parenthèses construit une valeur du type spécifié compte tenu de la liste d'expressions. Si la liste d'expression est une seule expression, l'expression de conversion de type est équivalente (dans la définition, et si définie dans la signification) à l'expression coulé correspondante (5.4)

(mon emphase). Cela signifie donc que xxx

et xxx

sont complètement identiques les uns aux autres. C'est à vous de choisir ce que vous trouverez plus facile à écrire.

Quant à votre deuxième question, dans l'exemple que vous avez donné avec les modèles et le tableau, je crois que ce que vous vouliez écrire était quelque chose comme ceci. xxx

ici, n ainsi que t est un paramètre de modèle, ce qui vous permet de transmettre n'importe quel Array que vous souhaitez que le compilateur remplisse n avec le nombre d'éléments dans la matrice. Si cela a l'air déroutant (quoi sur Terre est t (&) [n] ?), C'est parce que cette fonction prend dans un paramètre de type t (&) [n] . Pour que cela soit un peu plus facile à lire, donnons à ce paramètre un nom, comme indiqué ici: xxx

Je pense que cela rend cela un peu plus facile à lire. Mais que signifie cette déclaration? xxx

ceci déclare une variable appelée tableau qui est une référence à un tableau de t S de n éléments. Vous pouvez en effet déclarer des références aux tableaux, comme vous pouvez déclarer des pointeurs à des tableaux. Ce n'est pas très courant dans la pratique, mais dans ce type de modèle particulier, c'est un excellent moyen de déduire le compilateur de la taille de la matrice pour vous, car il essaie de faire correspondre la matrice à l'argument de modèle.

Le Raison des parenthèses dans ce cas est que si vous écrivez xxx

le compilateur analyserait cette "variable appelée tableau c'est un tableau de < code> n objets, chacun d'entre eux étant un t & . Toutefois, la spécification C ++ désactive spécifiquement des réseaux de références, et cela serait illégal. Les parenthèses le désambiguent explicitement. Ceci est similaire à Pointeurs de fonction - Vous écrivez xxx

au lieu de xxx

pour rendre le compilateur réaliser que le * signifie que Fonctionpointer est un pointeur, plutôt qu'une fonction qui renvoie un vide * .

comme pour la façon dont le compilateur détermine quand le compilateur détermine quand le compilateur détermine de chaque façon, les règles sont assez complexes et il y a en fait quelques circonstances Positions dans lesquelles le compilateur n'animiera pas votre expression à la manière prévue. L'un de ces cas est quelque chose de fait appel à une "analyse la plus vexante" dans laquelle le compilateur traite ce qui ressemble à la construction d'objets en tant que prototype de fonction. À titre d'exemple, ce code: xxx

est pas créer un vecteur appelé v < / Code> Initialisé à l'aide du constructeur par défaut. Au lieu de cela, il traite cela comme prototype de fonction pour une fonction appelée V qui ne prend aucun argument et produit un vecteur ! Cependant, si vous deviez écrire xxx

, le compilateur peut déduire sans ambiguïté qu'il s'agit d'une déclaration d'un vecteur passant 10 comme argument de constructeur, car il ne sera aucun moyen de traiter comme un prototype de fonction. §6.8 et §8.2 de la spécification gère ces cas en disant que tout ce qui peut être traité comme une déclaration sera, et tout ce qui peut être traité comme un prototype de fonction sera aussi aussi.

Le cas de parenthèses dans le contexte de la matrice (c'est-à-dire t (et tableau) [n] ) est géré par un autre morceau de logique car dans le contexte dans lequel vous déclarez une variable ou définissant un paramètre Dont le type nécessite une parenthèse explicite, il ne peut y avoir aucune ambiguïté quant à votre intention, car il est clair du contexte que vous nommez un type afin de déclarer une variable.

à résumer -

  1. moulages de la forme t (valeur) et (t) la valeur est identique.
  2. Les parenthèses dans t (& array) [n] sont d'empêcher le compilateur de se lier le & à t au lieu de Array comme prévu.
  3. L'utilisation particulière de la parenthèse est généralement déduite du contexte, bien que certains problèmes puissent se présenter entre les déclarations variables et les prototypes de fonctions.

    J'espère que cela vous aide!


1 commentaires

Impressionnant. Merci pour l'explication détaillée. Je vais le lire à nouveau et encore plusieurs fois jusqu'à ce qu'il soit synchronisé dans ma déprocession de pensée.



0
votes

de C ++ 14 annexe A, la liste complète la liste des cas où des parenthèses peuvent apparaître dans la grammaire est la suivante: xxx

Notez que:

  • Les règles de préprocesseur pour if-group et elif-group font référence à constante-expression . .
  • lparen désigne un ( sans blancheur précédent
  • la règle pour brut-chaîne est pendant la lexing, donc le ( et ) ne devient pas de jetons.
  • Toute séquence de jetons valides peut apparaître dans un groupe de préprocesseur dont la condition s'évalue sur False.

    Dans votre question, vous utilisez les éléments suivants:

    • Expression fausse: (type-ID) EXPRESSION CASSE
    • postfix-expression: spécificateur de type simple (expression-list_opt)
    • paramètres-and-calificateurs: (paramètre-déclaration-clause) attribut-spécificateur-SEQ_OPT CV-Qualififier-SEQ_OPT REF-Qualifier_OPT Exception-Spécification_OPT
    • NOPTR-ABSTRACT-DÉCLARATOR: (déclarateur PTR-Abstract)

0 commentaires