C++ la fonction de retour de la fonction
Où dans la norme sont des fonctions retournant des fonctions interdites? Je comprends qu'ils sont conceptuellement ridicule, mais il me semble que la grammaire leur permettrait. Selon cette page, un "noptr-déclaration [est] pour être valable, toute demande de déclaration", qui devrait inclure la déclaration d'une fonction:
int f()();
Qui concerne la syntaxe.
Il me semble que la syntaxe, comme énoncé dans [dcl.decl], permet
int f(char)(double)
qui pourrait être interprété comme la fonction f
qui prend un char
et retourne une fonction avec la même signature que int g(double)
.
1 declarator:
2 ptr-declarator
3 noptr-declarator parameters-and-qualifiers trailing-return-type
4 ptr-declarator:
5 noptr-declarator
6 ptr-operator ptr-declarator
7 noptr-declarator:
8 declarator-id attribute-specifier-seq opt
9 noptr-declarator parameters-and-qualifiers
10 noptr-declarator [ constant-expression opt ] attribute-specifier-seq opt
11 ( ptr-declarator )
12 parameters-and-qualifiers:
13 ( parameter-declaration-clause ) cv-qualifier-seqAfter
Grosso modo, après
1->2, 2=4, 4->6, 4->6
vous devriez avoir
ptr-opérateur ptr-opérateur ptr-opérateur
Ensuite, l'utilisation 4->5, 5=7, 7->8 pour la première demande de déclaration; l'utilisation 4->5, 5=7, 7->9 pour la deuxième et la troisième declarators.
- C chemin - de retour void *, et de le jeter à la fonction 🙂 C++ moyen - retour référence ou un pointeur vers un objet qui a une fonction (modèle de stratégie)
- C'est vraiment de très mauvais conseils. Même en C, vous pouvez retourner un pointeur de fonction. En C++, vous pouvez utiliser std::function, ou de tout objet appelable.
- Linux'
signal
fonction est un exemple typique d'une fonction retournant une autre fonction (pointeur), et je ne pense pas que c'est ridiculus. La seule chose ridiculus est la syntaxe:void (*signal(int signo, void (*func )(int)))(int);
- Qui n'a pas de retour d'une fonction. Elle renvoie un pointeur de fonction.
- Bon, bien, maintenant vous êtes de faire la même erreur que Anzurio. L'OP n'a pas dit que le retour des pointeurs de fonction est ridicule. À tous.
- Merde. Lire la question, comme si l'OP veut revenir pointeurs de fonction et non des fonctions.
- Vous vous trompez en pensant que C++ est principalement défini par une grammaire. La grammaire ne signifie pas grand-chose (et est connu pour être extrêmement ambiguë pour le C++, c'est pourquoi le codage C++ analyseurs est ennuyeusement difficile, et donc, c'est la lecture de code C++!)
- J'ai enfin downvoted la question, parce que c'est un mélange de grammaire et de définition de langage qui, pour le C++ en particulier (et, malheureusement, à mon humble avis) est très différent. C'est pourquoi le C++ est si difficile à lire, difficile à apprendre, difficile à analyser (tout cela à cause de l'héritage et l'arrière de look&feel compatibilité avec C raisons)
- la grammaire et le langage de définition ont été secoué, pas remué. Alors, pourquoi est le mélange de mauvais?
- Vous mentionnez que la grammaire serait de leur permettre, et vous avez raison; ce n'est pas la grammaire qui interdit cela. Mais j'ai bien compris votre question en vous demandant certains de la syntaxe de la règle de l'interdire (et il n'en existe pas, puisque c'est une sémantique de l'émission)
- La question est "Où est dans la norme sont des fonctions retournant des fonctions interdites?" Il n'est pas qualifié en demandant une syntaxe spécifique à la règle.
- la phrase suivante à la question est la fin de la "il me semble que la grammaire serait de leur permettre", et peut donc être compris (au moins par la non-anglophone que je suis) pourquoi la grammaire est rébarbatif que...
- Il n'y a rien sur le plan conceptuel ridicule sur les fonctions de retour des fonctions. Il a fait tout le temps dans d'autres langues. il est même fait en C++ sous la forme de fonctions de renvoi de fermetures.
- Double Possible de Fonction retournant une expression lambda
Vous devez vous connecter pour publier un commentaire.
De [dcl.fct], assez explicitement:
Avec C++11, vous voulez probablement seulement:
Il existe une certaine confusion concernant le C++ de la grammaire. La déclaration
int f(char)(double);
peut être analysé selon la grammaire. Voici un arbre d'analyse:En outre, une telle analyser est même significatif basé sur [dcl.fct]/1:
Dans cet exemple
T == int
,D == f(char)(double)
,D1 == f(char)
. Le type de la de demande de déclaration-id dansT D1
(int f(char)
) est "fonction de (char) de retour de type int". Donc dérivés de la déclaration de type de liste est "fonction de (char) de retour". Ainsi, le type def
seront lus comme "fonction (char) de retour de la fonction de la (double) de retour de type int."Au final c'est beaucoup de bruit pour rien, comme cela est explicitement interdite formulaire de demande de déclaration. Mais pas par la grammaire.
Avec C++11 (mais pas les versions précédentes de C++), vous pouvez retourner non seulement C-comme des pointeurs de fonction, mais aussi en C++ fermetures, notamment avec les fonctions anonymes. Voir aussi std::function
La norme interdit (sémantiquement, pas du point de vue syntaxique - donc il est pas une question de grammaire ; voir Barry répondre pour la citation) retour fonctions (et aussi interdire
sizeof
sur les fonctions!) mais permet de revenir pointeurs de fonction.BTW, je ne pense pas que vous pourriez revenir ensemble de fonctions. Ce que cela signifierait? Comment voulez-vous mettre cela en œuvre? En pratique, une fonction est certain bloc de code, et son nom est (comme pour les tableaux) un pointeur vers le début de la fonction du code machine.
Un joli truc peut être de construire (à l'aide de mécanismes à l'extérieur de la norme C++) d'une fonction au moment de l'exécution (et puis la manipulation du pointeur de fonction). Certaines bibliothèques externes peut permettre que: vous pouvez utiliser un JIT de la bibliothèque (par exemple,asmjit, gccjit, LLVM ...) ou tout simplement de générer le code C++, puis compiler et dlopen & dlsym sur POSIX systèmes, etc.
PS. Vous avez probablement raison, dans la compréhension que le C++11 grammaire (l'EBNF règles de la norme) ne rejette pas de retour des fonctions. C'est un sémantique de la règle indiqué dans la plaine de l'anglais qui n'admet pas que (c'est pas toute règle de grammaire). Je veux dire que l'EBNF seuls permettent:
et c'est pour la sémantique raisons (pas à cause de l'EBNF règles) qu'un compilateur est, à juste titre, rejetant le code ci-dessus. Pratiquement parlant, la la table des symboles est très important pour le compilateur C++ (et c'est pas de syntaxe ou de grammaire libre de tout contexte).
La triste réalité de C++, c'est que (pour des raisons d'héritage) sa grammaire (seul) est très ambiguë. Donc C++11 est difficile à lire (pour les humains), difficile à écrire (pour les développeurs), difficile à analyser (pour les compilateurs), ....
struct func{unsigned char[1024];};
et de revenir, alors vous seriez de retour de la fonction entière.struct
pas une fonction.Fait en C on ne peut pas passer ou le retour de la fonction. Seulement un pointeur d'adresse/de la fonction peut être transmis/retournés, ce qui est conceptuellement très proche. Pour être honnête, grâce à la possibilité de ommiting
&
et*
avec des pointeurs de fonction que l'on ne devrait pas vraiment si la fonction ou le pointeur est passé (sauf s'il contient des données statiques). Ici est simple déclaration de pointeur de fonction:foo est le pointeur de fonction de retour nulle et sans arguments.
En C++ ce n'est pas tellement différent. On peut toujours utiliser C-style des pointeurs de fonction ou de nouvelles
std::function
objet pour tous appelable créations. C++ ajoute également les expressions lambda qui sont des fonctions en ligne qui fonctionnent en quelque sorte semblables à des fermetures dans les langages fonctionnels. Il vous permet de ne pas faire tous passé fonctions mondiale.Et enfin - de retour de la fonction de pointeur ou
std::function
peut sembler ridicule, mais il est vraiment pas. Par exemple, l'état de la machine motif est (dans la plupart des cas), basé sur le retour pointeur vers la fonction de manipulation suivante état ou remboursables par anticipation à côté d'état de l'objet.La grammaire formelle de C effectivement interdit le retour des fonctions, mais, on peut toujours retourner un pointeur de fonction qui, à toutes fins et intentions, semble correspondre à ce que vous voulez faire:
Je suis figé dans dire, la grammaire, est l'un des plus fondamentaux de l'explication de l'absence de soutien d'une telle fonction. Les règles sont un type de préoccupation.
Si la grammaire n'est pas une façon d'accomplir quelque chose, je ne pense pas que ce qui importe est ce que la sémantique ou de la norme dit que pour un contexte donné, de langue gratuit.
typedef int sigfun_T(std::string);
est légal C++ syntaxe, mais il n'a pas de sensSauf si vous êtes de retour d'un pointeur ou une référence à une fonction qui est ok, l'alternative est de retour une copie d'une fonction. Maintenant, pensez à ce qu'une copie d'une fonction ressemble, les actes, se comporte comme. Que, tout d'abord serait un tableau d'octets, ce qui n'est pas autorisé, et le deuxième de tous ces octets est l'équivalence d'un morceau de code littéralement retourner un morceau de code....presque tous les heuristiques scanners de virus jugent qu'un virus, car il y aurait également aucun moyen de vérifier la viabilité du code retourné par le système d'exécution ou même au moment de la compilation. Même si vous pouviez retourner un tableau, comment feriez-vous pour le retour d'une fonction? Le principal problème avec renvoyant un tableau (ce qui serait une copie sur la pile), c'est que la taille n'est pas connue et donc il n'y a aucun moyen de le retirer de la pile, et le même dilemme existe pour les fonctions (d'où le tableau serait le langage machine binaire code). Aussi, si vous l'avez fait retour une fonction dans ce mode, comment voulez-vous tourner autour et à l'appel de cette fonction?
Pour résumer, la notion de retour d'une fonction, plutôt que d'un point pour une fonction échoue parce que la notion de ce qu'est une inconnue de taille de tableau de machine de code placé (copié) sur la pile. Ce n'est pas quelque chose que le C ou le C++ a été conçu pour permettre, et avec le code il y a maintenant moyen de tourner autour et à l'appel de cette fonction, en particulier, je vous voulais passer des arguments.
J'espère que cela a un sens