Quelle est la différence entre std :: function <> et un pointeur de fonction standard?
C'est:
typedef std::function<int(int)> FUNCTION;
typedef int (*fn)(int);
Sont-ils effectivement la même chose?
Quelle est la différence entre std :: function <> et un pointeur de fonction standard?
C'est:
typedef std::function<int(int)> FUNCTION;
typedef int (*fn)(int);
Sont-ils effectivement la même chose?
Ils ne sont pas du tout la même chose. std::function
est complexe, lourd, dynamique, proche de la magie de type qui peut contenir toute sorte de appelable entité, tandis que un pointeur de fonction est vraiment juste un simple pointeur. Si vous pouvez sortir avec elle, vous devriez préférer soit nu pointeurs de fonction ou auto
-bind
/auto
-lambda types. Utilisez uniquement std::function
si vous avez vraiment besoin d'un moyen systématique de l'organisation d'une collection hétérogène de appelable entités, telles que les fonctions, les foncteurs, la capture des lambdas et de lier des expressions.
Mise à jour: Un peu d'explications à propos de auto
types: Comparer les deux fonctions suivantes:
void do_something_1(std::function<void(int)> f, int a) { f(a); }
template <typename F, typename A> void do_something_2(F f, A a) { f(a); }
Maintenant, imaginez les invoquer avec un lambda ou un bind
expression:
do_something_X([foo, &bar](int n){ bar += n*foo; }, 12);
do_something_X(std::bind(X::bob, &jim, true, _1, Blue), 13);
La deuxième version du modèle est plus efficace, car dans les deux cas, l'argument F
est déduite du réel, de l'inconnaissable type de l'expression. La première version, avec std::function
, n'est pas un modèle et peut paraître plus simple et plus délibérée, mais il toujours les forces de la construction de l' std::function
objet, et peut-être porte plusieurs type d'effacement virtuel et coûts d'expédition.
Un pointeur de fonction est l'adresse d'une fonction réelle définie en C++. Un std::function
est un wrapper qui peut contenir n'importe quel type d'objet appelable (des objets qui ressemblent à des fonctions).
struct FooFunctor
{
void operator()(int i) {
std::cout << i;
}
};
// Since `FooFunctor` defines `operator()`, it can be used as a function
FooFunctor func;
std::function<void (int)> f(func);
Ici, std::function
vous permet de faire abstraction exactement ce genre d'objet appelable c'est vous traitez — vous ne savez pas c'est FooFunctor
, vous savez juste qu'il retourne void
et a un int
paramètre.
Un exemple réel où cette abstraction est utile lorsque vous êtes à l'aide de C++ avec un autre langage de script. Vous pourriez concevoir une interface qui peut traiter à la fois des fonctions définies en C++, ainsi que des fonctions définies dans le langage de script, de manière générique.
Edit: Liaison
Aux côtés std::function
,, vous trouverez également std::bind
. Ces deux sont des outils très puissants lorsqu'ils sont utilisés ensemble.
void func(int a, int b) {
// Do something important
}
// Consider the case when you want one of the parameters of `func` to be fixed
// You can used `std::bind` to set a fixed value for a parameter; `bind` will
// return a function-like object that you can place inside of `std::function`.
std::function<void (int)> f = std::bind(func, _1, 5);
Dans cet exemple, la fonction de l'objet renvoyé par bind
prend le premier paramètre, _1
, et le transmet func
le a
paramètre, et définit b
à la constante 5
.
Un std :: function a un état. Il peut contenir des paramètres supplémentaires "liés" dans celui-ci.
Ces paramètres peuvent aller d’autres choses que d’autres classes, d’autres fonctions ou même ces pointeurs pour les appels de fonctions membres.
Le pointeur de la fonction de remplacement n'est pas typedef int (*fn)(int);
Il s’agit de typedef int (*fn)(void*,int);
, avec le vide * reprenant l’état qui serait caché dans la fonction std ::.
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.