c++: keine passende Funktion für Aufruf, aber der Kandidat hat exakt die gleiche Signatur
g++ beschwert sich über
myclass.cxx:185: error: no matching function for call to 'IMyInterface::doSomething(const SomeClass*, unsigned int)'
IMyInterface.h:34: note: candidates are: virtual void IMyInterface::doSomething(const SomeClass*&, unsigned int)
wenn ich Anrufe,
m_instanceOfInterface->doSomething((const SomeClass*)0,(unsigned int)1);
Alle Zeiger auf warum? Es scheint mir, dass g++ ist zu sehen, dass genau die gleiche Signatur zwischen dem, was erklärt wird und was aufgerufen wird, aber trotzdem beschwert sich darüber, keine passende Funktion gefunden.
Kann ich nennen, im gleichen Zusammenhang, eine andere Funktion des IMyInteface
, IMyInterface::doSomethingElse(float& p)
. Also irgendwie die const
ist das problem?
Habe ich nicht übergeben den NULL-Zeiger und warf eine Konstante ganze Zahl, nur so zum Spaß... ursprünglich habe ich
m_instanceOfInterface->doSomething((const SomeClass*)m_someDerivedClass,m_anInteger);
und bekam den gleichen Fehler. Also habe ich beschlossen, zu klären, Dinge, die mit g++, indem einige explizite Argumente. Ich kann Ihnen versichern, dass der NULL-Zeiger ist NICHT das problem - obwohl verständlich, wir alle duckte sich ein wenig, wenn man eine NULL übergeben wird mit const
🙂
- Funktioniert es, wenn Sie den Mauszeiger vor dem Aufruf der Funktion? Ich meine
const SomeClass* ptr = 0;
und dannm_instance->doSomething (ptr, 1)
- PS: bitte fügen Sie den funktionskopf (Deklaration in der header), könnte das helfen...
- Das (d.h. die Schaffung Zeiger vor dem Aufruf) das problem gelöst! Aber warum g++ geben, wie kryptische Nachricht?
- Es ist ein syntax Fehler, du hast vergessen eine Klammer. Auch, warum warf einen integer? Sie können nur sagen
1U
. - SB: Oder nur 1 Punkt. Der compiler ist intelligent genug, um zu wissen, wie man werfe einen positiven
int
zu einemunsigned int
. template <typename T> foo(T, T); unsigned int bar(); foo(bar(), 1);
🙁- Die Fehlermeldung macht es so Aussehen, als wenn es nur einen Kandidaten, wobei
unsigned int
. Aber es ist zumindest möglich, dass die Fehlermeldung abgeschnitten wurde, nur um zu zeigen die Kandidaten, dass der Fragesteller denkt, sollten aufeinander abgestimmt werden, und es gibt auch eineint
überlastung. Oder werden in Zukunft. Nicht, dass Sie oft sorgen über solche Dinge, aber es wäre falsch zu vermuten, dass1
wird es immer tun. - Sie können auch dieses Problem beheben, indem die Deklaration der Funktion wie
doSomething(const SomeClass *const &, unsigned int)
. Auch müssen Sie nicht dieconst
beim ausspielen von 0 bisSomeClass *
(obwohl es nicht schadet)
Du musst angemeldet sein, um einen Kommentar abzugeben.
Benötigt die Funktion das argument von nicht-const-Referenz, die nicht binden können, um eine temporäre. Beachten Sie:
In deinem Fall
T = SomeClass const *
. Also, Sie haben eine nicht-temporäre:Beachten Sie, dass der Zweck dieser ist es vermutlich zu füllen
pc
mit einigen sinnvollen Wert, so sicher zu integrieren, dass apporpriately.void doSomething(unsigned int &a) { a += 1; }
zu einem Fehler führen, wenn Sie versuchen, es zu nennen, wiedoSomething(1);
oder sogardoSomething((unsigned int)1);
. Dieser Aufruf ändern würde, eine temporäre, das wird sofort verworfen, und es wurde angenommen (zu Recht oder zu Unrecht), dass dies nicht das ist, was du meinst zu tun. Es ist besonders fehleranfällig, da ruft es wieint i = 1; doSomething(i);
verlassen würdei
gleich 1 ist, in der Erwägung, dassunsigned int i = 1; doSomething(i);
würde eigentlich Inkrementi
. Bugtastic.time()
(oder irgendetwas anderes mit einem optionalen aus-param), um einen Referenz-parameter anstelle von Zeiger-parameter und übergeben Sie in einem temporären anstelle von null, wenn Sie kümmern sich nicht um das Ergebnis, und die Implementierung muss nicht speziellen-Fall null-oder bieten überlastungen, um die parameter formal optional. So ist es nur fast nutzlos, eher als nie nützlich, und ich vermute, dass der potentielle nutzen nicht betrachtet überwiegen die wahrscheinlichen Fehler.const
, so der Anrufer, sollten Sie nicht erwarten, dass die parameter zu ändern, obwohl der Parameter wird per Referenz übergeben?int x = compute(char[100]());
etc...void doSomething(const SomeClass* &ptrref, unsigned int) { ptrref = 0; }
gültig ist, wird der Zeiger vom Aufrufer bereitgestellte, auf null.ptrref
einfach nicht const. Es ist möglich, dass Sie gemeint zu erklären, dass der parameter entweder alsSomeClass * const &
oder alsconst SomeClass *const &
, obwohl es nicht viel Sinn, die übergabe einer const-Referenz auf einen Zeiger, da Zeiger ist eine kleine Art, Sie könnte genauso gut gehen Sie von Wert für die meisten Zwecke.Bearbeiten
Korrigiert zu reflektieren Kommentare.
Der Kandidat nicht haben genau die gleiche Signatur. Die Funktion übernimmt eine Referenz auf ein const-Zeiger auf eine
SomeClass
, und Sie sind die Zeiger. In der Tat, Sie bieten eine besonders Fiese Zeiger auf die Funktion.Ein großes problem ist hier, dass null-Zeiger. Müssen Sie dem compiler etwas fester, so kann er den Bezug von it. Sie geben einen null-Zeiger.
NULL
Referenz (non-const
)? Es scheint in den meisten Fällen sollten Sie versuchen, dass, wäre es zu einem compiler-Fehler, anstatt Undefiniertes Verhalten. Vielleicht habe ich einfach nicht gedacht habe, nichts.const SomeClass *ptr = 0; doSomething(ptr, 1);
ist erlaubt, auch wennptr
null ist, vorausgesetzt natürlich, dassdoSomething
nicht dereferenzieren es durch das schreiben*ptr
.SomeClass *ptr = new SomeClass; doSomething((const SomeClass *)ptr, 1);
ist nicht erlaubt, auch wenn(const SomeClass *)ptr
ist nicht null, weil das Ergebnis aus einem Guss (nicht-Referenz-Typ) ist eine vorübergehende.NULL
Verweis, der wirklich kompiliert wäre eine Referenz auf einen Zeiger, Punkte zuNULL
-- das ist nicht UB, bis Sie wirklich dereferenzieren es. Ich denke, dass ich falsch interpretiert. 🙁Ihre Funktion benötigt ein nicht-const Referenz auf einen Zeiger, nicht ein Zeiger. Sie können nicht erstellen Sie eine non-const Referenz aus einem literal (d.h. der null-Zeiger), damit der compiler nicht in der Lage ist, um die Funktion aufzurufen, die mit dem ersten argument '0' und er sucht sich eine überlastung der Einnahme das erste argument (der Zeiger) kopieren.