En C, std::function est une classe de modèle qui représente un objet appelable . Il fournit un moyen flexible de transmettre des fonctions sous forme d'arguments et de les stocker dans des structures de données. Cependant, une source courante de confusion survient quant à savoir si l'argument modèle (signature) de std::function fait partie de son type. Cet article approfondit les détails de cette ambiguïté et explore des solutions potentielles.
L'ambiguïté survient lorsque plusieurs surcharges d'une fonction acceptent des paramètres de signatures différentes mais sont toutes deux constructibles à partir du même type. , tels que les pointeurs de fonction ou les lambdas. Considérez l'extrait de code suivant :
<code class="cpp">#include <functional> using namespace std; int a(const function<int ()>& amp;f) { return f(); } int a(const function<int (int)>& amp;f) { return f(0); } int x() { return 22; } int y(int) { return 44; } int main() { a(x); // Call is ambiguous. a(y); // Call is ambiguous. a((function<int ()>&)x); // Works. a((function<int (int)>&)y); // Works. return 0; }</code>
Dans cet exemple, la fonction a est surchargée pour accepter soit un pointeur de fonction de type function
Cette ambiguïté découle de la fait que std::function utilise l'effacement de type, ce qui lui permet de stocker et d'appeler des fonctions de différents types. L'argument de modèle (signature) de std::function sert d'espace réservé pour spécifier le type appelable, mais il n'est pas strictement appliqué lors de la construction.
Par exemple, le constructeur de std::function peut accepter n'importe quel type qui peut être converti en un objet appelable, même si la signature ne correspond pas à l'argument du modèle. Cette flexibilité dans la construction conduit à l'ambiguïté lorsque plusieurs surcharges acceptent des types peu constructibles.
Pour résoudre l'ambiguïté, un casting explicite peut être utilisé pour spécifier la signature souhaitée au point de fonction. invocation. Cela garantit que le compilateur peut identifier la surcharge correcte en fonction du type de conversion. Dans l'exemple ci-dessus, les conversions suivantes peuvent être ajoutées pour lever l'ambiguïté des appels :
<code class="cpp">a((function<int ()>&)x); // Disambiguate as function<int ()> a((function<int (int)>&)y); // Disambiguate as function<int (int)></code>
Alternativement, des objets de fonction du type approprié peuvent être créés et transmis directement à la fonction a :
<code class="cpp">function<int ()> fx = x; function<int (int)> fy = y; a(fx); // No ambiguity a(fy); // No ambiguity</code>
Enfin, des techniques de métaprogrammation de modèles peuvent être utilisées pour générer des fonctions spécialisées pour les différentes signatures, éliminant ainsi le besoin de casting explicite. Cette approche fournit une solution plus élégante et plus sûre.
La signature de std::function sert d'espace réservé pour spécifier le type appelable, mais elle n'impose pas strictement la correspondance de type pendant la construction. Cette flexibilité peut conduire à une ambiguïté lorsque plusieurs surcharges acceptent des types peu constructibles. En utilisant un casting explicite ou des approches alternatives telles que des objets de fonction ou une métaprogrammation de modèles, les développeurs peuvent lever l'ambiguïté des appels de fonction et garantir que la surcharge correcte est choisie.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!