In C ist std::function eine Vorlagenklasse, die ein aufrufbares Objekt darstellt . Es bietet eine flexible Möglichkeit, Funktionen als Argumente zu übergeben und in Datenstrukturen zu speichern. Allerdings entsteht häufig Verwirrung darüber, ob das Vorlagenargument (Signatur) von std::function Teil seines Typs ist. Dieser Artikel befasst sich mit den Details dieser Mehrdeutigkeit und untersucht mögliche Lösungen.
Die Mehrdeutigkeit entsteht, wenn mehrere Überladungen einer Funktion Parameter mit unterschiedlichen Signaturen akzeptieren, aber beide aus demselben Typ konstruierbar sind , wie etwa Funktionszeiger oder Lambdas. Betrachten Sie den folgenden Codeausschnitt:
<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>
In diesem Beispiel wird die a-Funktion überladen, um entweder einen Funktionszeiger vom Typ function
Diese Mehrdeutigkeit ergibt sich aus der Tatsache ist, dass std::function Typlöschung verwendet, die es ihm ermöglicht, Funktionen unterschiedlicher Typen zu speichern und aufzurufen. Das Vorlagenargument (Signatur) von std::function dient als Platzhalter zur Angabe des aufrufbaren Typs, wird jedoch während der Konstruktion nicht strikt erzwungen.
Zum Beispiel kann der Konstruktor von std::function jeden Typ akzeptieren das in ein aufrufbares Objekt konvertiert werden kann, auch wenn die Signatur nicht mit dem Vorlagenargument übereinstimmt. Diese Flexibilität in der Konstruktion führt zu Mehrdeutigkeit, wenn mehrere Überladungen lose konstruierbare Typen akzeptieren.
Um die Mehrdeutigkeit aufzulösen, kann explizites Casting verwendet werden, um die gewünschte Signatur am Punkt der Funktion anzugeben Aufruf. Dadurch wird sichergestellt, dass der Compiler die richtige Überladung basierend auf dem Umwandlungstyp identifizieren kann. Im obigen Beispiel können die folgenden Casts hinzugefügt werden, um die Aufrufe eindeutig zu machen:
<code class="cpp">a((function<int ()>&)x); // Disambiguate as function<int ()> a((function<int (int)>&)y); // Disambiguate as function<int (int)></code>
Alternativ können Funktionsobjekte des entsprechenden Typs erstellt und direkt an die Funktion a übergeben werden:
<code class="cpp">function<int ()> fx = x; function<int (int)> fy = y; a(fx); // No ambiguity a(fy); // No ambiguity</code>
Schließlich können Template-Metaprogrammierungstechniken verwendet werden, um spezielle Funktionen für die verschiedenen Signaturen zu generieren, wodurch die Notwendigkeit einer expliziten Umwandlung entfällt. Dieser Ansatz bietet eine elegantere und typsicherere Lösung.
Die Signatur von std::function dient als Platzhalter für die Angabe des aufrufbaren Typs, erzwingt jedoch keine strikte Typübereinstimmung während der Konstruktion. Diese Flexibilität kann zu Mehrdeutigkeiten führen, wenn mehrere Überladungen Typen akzeptieren, die lose konstruierbar sind. Durch die Verwendung von explizitem Casting oder alternativen Ansätzen wie Funktionsobjekten oder Template-Metaprogrammierung können Entwickler Funktionsaufrufe eindeutig machen und sicherstellen, dass die richtige Überladung ausgewählt wird.
Das obige ist der detaillierte Inhalt vonIst das Vorlagenargument (Signatur) von „std::function' Teil seines Typs?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!