37 votes

Une fonction std::peut-elle stocker des pointeurs vers des membres de données ?

Desde Référence cpp J'ai trouvé ça :

Le modèle de classe std::function est une enveloppe de fonction polymorphe à usage général. Les instances de std::function peuvent stocker, copier et invoquer n'importe quelle cible Callable -- fonctions, expressions lambda, expressions bind ou autres objets de fonction, ainsi que des pointeurs vers des fonctions membres et des objets de fonction. pointeurs vers des membres de données .

Je ne vois pas pourquoi un std::function devrait être capable de stocker un tel pointeur et je n'ai jamais entendu parler de cette fonctionnalité.
Est-il vraiment possible que j'aie manqué quelque chose ou qu'il s'agisse d'une erreur dans la documentation ?

Comment le operator() se comporter dans un tel cas ?
Dès le [documentation](http://en.cppreference.com/w/cpp/utility/functional/function/operator()) :

Invoque la fonction appelable stockée cible avec les paramètres args.

De toute façon, il n'y a pas de cible de fonction stockée appelable à invoquer ici. Ai-je tort ?

Pour être honnête, je n'arrive même pas à déterminer quelle est la bonne syntaxe pour une telle fonction, sinon j'aurais écrit un exemple pour la tester.
Comment le modèle suivant pourrait-il être utilisé pour définir un pointeur vers un membre de données ?

template< class R, class... Args >
class function<R(Args...)>

10 votes

0 votes

Désolé, j'ai mal lu. :(

0 votes

Ok, donc l'idée est la même que celle utilisée pour les méthodes membres : la signature est exactement la même, mais pour le premier paramètre qui est l'instance sur laquelle les invoquer. Une approche similaire peut être utilisée pour les membres de données, n'est-ce pas ? Intéressant.

26voto

Piotr S. Points 9759

L'effet d'un appel à l'opérateur d'appel de fonction de std::function<R(ArgTypes...)> :

R operator()(ArgTypes... args) const

est équivalent à (§ 20.9.11.2.4 [func.wrap.func.inv]/p1 ):

INVOKE<R>(f, std::forward<ArgTypes>(args)...)

dont la définition comprend la puce suivante (§ 20.9.2 [func.require]/p1 ):

Définir INVOQUEZ (f, t1, t2, ..., tN) comme suit :

[...]

1.3 - t1.*f cuando N == 1 y f est un pointeur vers une donnée membre d'une classe T y t1 est un objet de type T ou une référence à un objet de type T ou une référence à un objet d'un type dérivé de T ;

alors, quand f est un pointeur vers un membre de données stocké dans un invokeur interne d'un fichier std::function alors le std::function doit lui-même définir un seul argument, par exemple :

std::function<int(std::pair<int,int>)> f = &std::pair<int,int>::first;

f(std::make_pair(1, 2));

DEMO

0 votes

Étant le type de retour de la fonction fonction le type réel de l'élément de données, non ?

1 votes

Ce R à la fin de INVOQUEZ signifie " implicitement convertible en R ", de sorte que le type de l'élément de données stocké peut être converti en ce qui suit std::function définit

0 votes

Wow, encore plus puissant que ce que je pensais. Je ne vois toujours pas d'utilité réelle d'une telle fonctionnalité, mais cela n'enlève rien à sa beauté ! Je vous remercie vraiment pour vos réponses, comme d'habitude, très appréciées :-)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X