2016-09-01 1 views

Répondre

9

L'utilisation d'un hyperlinked C++ grammar, l'analyse syntaxique de decltype(void()) est:

decltype(expression) 
decltype(assignment-expression) 
decltype(conditional-expression) 

... beaucoup d'étapes impliquant l'ordre des opérations vont ici ...

decltype(postfix-expression) 
decltype(simple-type-specifier (expression-listopt)) 
decltype(void()) 

Alors void() est une sorte de expression ici, en particulier un postfix-expression.

Plus précisément, l'article citant 5.2.3 [expr.type.conf] le paragraphe 2 de la norme de l'ISO 2011 C:

L'expression T(), où T est un simple spécificateur-type ou spécificateur de nom de type pour un type d'objet complet non-tableau ou le type (éventuellement qualifié cv) void, crée une prvalue du type spécifié , qui est initialisé en valeur (8,5, aucune initialisation n'est effectuée pour le cas void()).

Alors void() est une expression de type void, tout comme int() est une expression de type int (avec une valeur 0). Il est clair qu'une expression vide n'a aucune valeur, mais ici c'est l'opérande de decltype, donc elle n'est pas évaluée. decltype se réfère uniquement à son type d'opérande, pas à sa valeur.

decltype(void()) est simplement une manière verbeuse de faire référence au type void.

+2

@skypjack: Voir la norme C++ 11 (ou un brouillon), section 5.2.3 [expr.type.conv], paragraphe 2. Un * simple-type-specifier * suivi de parenthèses vides "crée une prvalue du type spécifié, qui est valueinitialized (8.5, aucune initialisation n'est effectuée pour le cas void()) ". Tout comme 'int()' est une expression de type 'int',' void() 'est une expression de type' void'. Et puisque c'est l'opérande de 'decltype', ce n'est pas évalué. 'decltype (void())' est simplement une façon complexe de faire référence au type 'void'. (Yakk, vous pourriez étendre votre réponse pour expliquer comment 'void()' est une expression.) –

+1

@Yakk Comme déjà mentionné dans les commentaires, l'expansion de la réponse avec plus de détails aiderait. +1 pour promouvoir la suggestion. Je vous remercie. – skypjack

+3

Je me suis permis d'ajouter une explication de ce que signifie 'void()'. S'il vous plaît vérifier ma mise à jour pour l'exactitude. –

4

Je cite la comment de @JoachimPileborg qui semble expliquer correctement:

Je pense que je pensais que ce maintenant, decltype a besoin d'une expression, et non un type. void() n'est pas un type ici, mais une expression, un cast de style C (juste comme par exemple int (12.34)) void (void) n'est pas une expression donc ça ne marche pas. La façon dont le compilateur analyse différentes choses dépend du contexte, lorsqu'il attend un type qu'il analyse en tant que type, quand il s'attend à ce qu'une expression soit analysée en tant qu'expression. sizeof() (avec les parenthèses) attend tout d'abord un type, sinon il est analysé comme une expression entre parenthèses.

Je ne recherche pas de crédits ou de réputation.
Quoi qu'il en soit, je suppose que c'était une réponse intéressante dans la réponse qui vaut une question dédiée pour les futurs lecteurs.

+0

Si vous ne voulez pas rep, vous pouvez marquer la réponse comme Wiki de la communauté – AndyG

+0

@skypjack cliquez sur "modifier" puis cochez la case "wiki communautaire" sous la fenêtre de texte – TemplateRex

+2

'void()' n'est pas un style C jeter.En C, une distribution se compose d'un nom de type entre parenthèses suivi d'une expression, par exemple '(void) 42'. Dans 'void()', le nom du type n'est pas entre parenthèses et n'est pas suivi d'une expression. –