human
Supposons que j'ai une fonction qui prend un ```std::function```:
```void callFunction(std::function x)
{
    x();
}
```
Devrais-je passer ```x``` par const-référence à la place ?:
```void callFunction(const std::function& x)
{
    x();
}
```
Est-ce que la réponse à cette question change en fonction de ce que la fonction en fait ? Par exemple, s'il s'agit d'une fonction membre de classe ou d'un constructeur qui stocke ou initialise le ```std::function``` dans une variable membre
gpt
Si vous voulez des performances, passez par valeur si vous le stockez.

Supposons que vous ayez une fonction appelée "exécuter ceci dans le thread de l'interface utilisateur".
```std::future run_in_ui_thread( std::function )
```
qui exécute du code dans le thread "ui", puis signale le ```future``` une fois terminé. (Utile dans les frameworks d'interface utilisateur où le thread de l'interface utilisateur est l'endroit où vous êtes censé manipuler les éléments de l'interface utilisateur)
Nous avons deux signatures que nous envisageons:
```std::future run_in_ui_thread( std::function ) // (A)
std::future run_in_ui_thread( std::function const& ) // (B)
```

Maintenant, nous allons probablement les utiliser comme suit:
```run_in_ui_thread( [=]{
  // le code va ici
} ).wait();
```
ce qui va créer une fermeture anonyme (un lambda), construire un ```std::function``` à partir de celle-ci, le passer à la fonction ```run_in_ui_thread```, puis attendre qu'il ait fini de s'exécuter dans le thread principal.
Dans le cas (A), le ```std::function``` est directement construit à partir de notre lambda, qui est ensuite utilisé dans le ```run_in_ui_thread```. Le lambda est ```move```d dans le ```std::function```, de sorte que tout état déplaçable est efficacement transporté dans celui-ci.
Dans le deuxième cas, un ```std::function``` temporaire est créé, le lambda est ```move```d dedans, puis ce ```std::function``` temporaire est utilisé par référence dans le ```run_in_ui_thread```.
Jusqu'à présent, tout va bien -- les deux se comportent de manière identique. Sauf que ```run_in_ui_thread``` va faire une copie de son argument de fonction pour l'envoyer dans le thread ui pour l'exécuter ! (il retournera avant d'en avoir fini avec lui, donc il ne peut pas simplement utiliser une référence). Pour le cas (A), nous ```move``` simplement le ```std::function``` dans son stockage à long terme. Dans le cas (B), nous sommes obligés de copier le ```std::function```.
Ce stockage rend le passage par valeur plus optimal. S'il y a une possibilité que vous stockiez une copie du ```std::function```, passez par valeur. Sinon, les deux méthodes sont à peu près équivalentes: le seul inconvénient de la valeur est si vous prenez le même ```std::function``` encombrant et que vous le faites utiliser une méthode secondaire après l'autre. À moins de cela, un ```move``` sera aussi efficace qu'une ```const&```.
Maintenant, il y a d'autres différences entre les deux qui se manifestent principalement si nous avons un état persistant dans le ```std::function```.
Supposons que le ```std::function``` stocke un objet avec un ```operator() const```, mais qu'il a également des membres de données ```mutable``` qu'il modifie (quelle impolitesse !).
Dans le cas de ```std::function const&```, les membres de données ```mutable``` modifiés se propageront hors de l'appel de fonction. Dans le cas de ```std::function```, ils ne le feront pas.
Il s'agit d'un cas relativement étrange.
Vous voulez traiter ```std::function``` comme vous le feriez avec tout autre type potentiellement lourd et facilement déplaçable. Le déplacement est bon marché, la copie peut être coûteuse.