Ich habe ein sehr einfaches Problem: Irgendwo gibt es eine Funktion
%Vor%, das zumindest durch argumentabhängige Namenssuche gefunden wird. Jetzt das Problem:
%Vor%Dies funktioniert nicht, da die Namenssuche nach dem Auffinden der Elementfunktion beendet wird.
Was muss ich in der angegebenen Zeile schreiben, damit not die Member-Funktion versucht wird, aufgerufen zu werden, sondern dass der Compiler alles tut, was die Member-Funktion nicht tun würde existieren?
Beachten Sie, dass die Lösung nicht ist, um ::size
zu schreiben, da dies den argumentabhängigen Namen verhindert Nachschlagen und funktioniert nur, wenn ich weiß wo size
deklariert ist.
Weitere Komplikationen:
Ich weiß, dass für jeden relevanten Typ T
, für den ich die unten stehende Template-Funktion B::doSomething
verwende, irgendwo eine Funktion
, das zumindest durch argumentabhängige Namenssuche gefunden wird. B
sieht folgendermaßen aus:
Ich möchte, dass die Nichtmitgliedsfunktion aufgerufen wird (von der ich sicher bin, dass sie existiert, aber ich kann mir nicht sicher sein, wo sie lebt).
Dies ist ein bekanntes Problem, und seine Lösung ist ebenso bekannt. Ich bin überrascht, dass es noch nicht erwähnt wurde. Wenn Sie eine Funktion haben, die kein Mitglied ist:
%Vor% Sie können die Namenssuche so gestalten, dass sie eine Elementfunktion mit einer using
-Deklaration vorziehen:
Wenn der Compiler den Aufruf von size(c)
sieht, beginnt er im innersten Bereich und sucht nach etwas mit dem Namen size
. Ohne die Deklaration using
hätte der Compiler die Member-Funktion im Klassenbereich vor dem Nicht-Member im globalen Namespace gefunden, aber die using
-Deklaration ändert dies. Der innerste Bereich ist die Funktion selbst und die using-Deklaration wird vor der Elementfunktion gefunden.
Das Schöne daran ist, dass Sie immer noch Argument-abhängige Suche (ADL) bekommen, weil der eigentliche Aufruf von size(c)
nicht qualifiziert ist. Dies bedeutet, dass Sie es in einer Vorlage verwenden können:
... und selbst wenn die korrekte Funktion size
in einem anderen Namensraum ist, wird sie von ADL gefunden. Die using
-Deklaration muss lediglich auf einige size
-Funktion verweisen, nicht unbedingt auf die, die Sie tatsächlich möchten. Es wäre normal, irgendwo eine Standardimplementierung zu haben, die vielleicht das Mitglied aufruft. Die nächste Version des C ++ - Standards (C ++ 17) hat fast sicher eine std::size
-Funktion, die genau das tut. Sobald dies weit verbreitet ist, können Sie
Im Moment können Sie entweder Ihre eigene Standardimplementierung bereitstellen, wie zum Beispiel:
%Vor% ... oder Sie können weiterhin auf die Version für C
verweisen und darauf vertrauen, dass ADL die richtige findet.
Sie können SFINAE verwenden, um zu erkennen, ob Sie eine Mitgliedsfunktion haben oder nicht.
Ich habe diese Antwort verwendet, um solche Templatests auf die Größe vorzubereiten:
%Vor%Nun, der Hauptteil, 2 Funktionen - aufgrund von SFINAE wird nur eine davon ausgewählt:
%Vor%Nun, auf auto-magische Weise - abhängig davon, ob Sie B :: size (C) haben oder nicht - wird die globale oder lokale Funktion aufgerufen:
%Vor% Es gibt Global size
aus. Um Local size
zu erhalten - aktiviere einfach die lokale B::size(C)
-Funktion. Dies kann nicht mit einer anderen Antwort erreicht werden ,,,,
Arbeitsbeispiel hier bei ideone
Tags und Links c++