Question

Si le message suivant du C ++ FAQ Lite est vrai: « un nom de fonction désintègre à un pointeur vers la fonction » (comme un nom de tableau désintègre à un pointeur sur son premier élément); pourquoi nous devons inclure l'esperluette?

typedef  int (Fred::*FredMemFn)(char x, float y);
FredMemFn p = &Fred::f;

Et pas seulement:

typedef  int (Fred::*FredMemFn)(char x, float y);
FredMemFn p = Fred::f;

Dans le second cas de Fred f est une fonction et peut se désintégrer à un pointeur vers cette fonction.

J'espère que cette question est stupide.

Était-ce utile?

La solution

Réponse originale:

parce qu'une fonction de membre n'est pas une fonction et un élément de fonction pointeur n'est pas une fonction pointeur. Par conséquent, les règles de décomposition ne sont pas applicables.

En outre, il existe un type de fonction en C ++, mais pas de type fonction membre. Ainsi, vous pouvez utiliser une fonction dans des endroits où l'on attend un pointeur à la fonction, mais vous ne pouvez pas utiliser un membre fonction parce qu'il n'y a pas une telle chose, seul pointeur à fonction membre. f dans votre exemple est une fonction. D'autre part, f Fred est ... eh bien, rien.

En outre, je dirais que « le nom d'une fonction peut se désintégrer ... ». Non, le nom ne peut rien faire, une lvalue de type fonction peut être implicitement converti en un pointeur à la fonction, ce qui est une conversion d'identité dans la mesure où la résolution de surcharge concerne

Modification de clarifier ma réponse:

Chaque expression en C ++ a un type et la valeur. Une valeur d'un type peut parfois être convertie en une valeur d'un autre type. Ces conversions sont classés de telle sorte que pour faire une meilleure conversion l'autre principalement pour la résolution de surcharge de fonction.

L'un des types de conversions est appelée lvalue à rvalue conversion. Lorsqu'un lvalue apparaît dans un contexte où un rvalue est nécessaire cette conversion a lieu. Habituellement, ce genre de conversion ne fait rien, par exemple:

int i = 4, j = 5;
i = j;

sur la deuxième ligne j est une lvalue, mais un rvalue est nécessaire ici, donc j est converti en un rvalue. Mais ce n'est pas une conversion observable, est-il? Mais il y a des cas où l'on peut observer la conversion lvalue à rvalue. C'est, une lvalue de réseau de n T peut être converti en un rvalue de type T* dont la valeur est l'adresse du premier élément du tableau et < em> une lvalue de type "fonction avec la signature S" un rvalue de type "pointeur de fonction avec la signature S" dont la valeur est l'adresse de la fonction

Cela signifie que lorsque nous attribuons une fonction à un pointeur à la fonction la fonction lvalue est implicitement convertie à son adresse.

void f() {}
void (*p) () = f; //f is converted to rvalue

f est une expression et a un type. le type de f est void()

Il n'y a pas de type en C ++ comme member-function Il y a des pointeurs membres-à-fonctions, mais pas les fonctions membres eux-mêmes. Je parle bien sûr de fonctions non statiques. Les fonctions statiques fonctionnent de la même manière que les fonctions ordinaires, qui est, vous ne devez pas écrire &X::f, au lieu que vous pouvez écrire X::f Pourquoi? Parce que X :: f a une fonction de type et la conversion mentionnée ci-dessus a lieu. Si f est non statique, cependant, X :: f est de type ... quoi? Ah oui, il ne dispose pas d'un type et est donc pas une expression et n'a donc pas de valeur et donc que la valeur ne peut être convertie en quoi que ce soit.

Citation de la norme: 5.3.1 clause 3 Un pointeur vers un membre ne se forme lorsqu'une explicite et est utilisé et son opérande est un identifiant non qualifié entre parenthèses. [Note: c'est l'expression et (ID qualifié), où l'ID qualifié est mis entre parenthèses, ne forme pas une expression de type « pointeur à un membre. » Ni ne-id qualifié, parce qu'il n'y a pas de conversion implicite d'un identifiant admissible pour une fonction membre non statique au « pointeur vers la fonction de membre » type comme il est d'une lvalue du type de fonction de type « pointeur de fonction » (4.3). Il n'est et non qualifié-id un pointeur vers un membre, même dans le cadre de la La classe non qualifiée-id. ]

Espérons que cela était plus clair ...

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top