Forum: Compiler & IDEs C++: Callback Funktion kann nicht aufgelöst werden


von J. S. (jojos)


Angehängte Dateien:

Lesenswert?

Ich möchte eine Memberfunktion als callback mit Argumenten aufrufen 
(Mbed EventQueue).

der Aufruf lautet:
1
queue.call(&finger, &Adafruit_Fingerprint::LEDcontrol, (uint8_t)FINGERPRINT_LED_ON, (uint8_t)0, (uint8_t)FINGERPRINT_LED_BLUE, (uint8_t)0);

das funktioniert auch, allerdings ist in der Klasse die Funktion 
überladen und es gibt zwei Signaturen:
1
  uint8_t LEDcontrol(bool on);
2
  uint8_t LEDcontrol(uint8_t control, uint8_t speed, uint8_t coloridx,
3
                     uint8_t count = 0);

Es funktioniert nur wenn es nur eine LEDControl() Funktion gibt, sonst 
scheint der Compiler das nicht auflösen zu können.
1
[build] /home/jojo/projects/mbed-ce-hello-world/app_Fingerprint/main.cpp:25:27: error: no matching function for call to 'events::EventQueue::call(Adafruit_Fingerprint*, <unresolved overloaded function type>, uint8_t, uint8_t, uint8_t, uint8_t)'
2
[build]    25 |                 queue.call(&finger, &Adafruit_Fingerprint::LEDcontrol, (uint8_t)FINGERPRINT_LED_ON, (uint8_t)0, (uint8_t)FINGERPRINT_LED_BLUE, (uint8_t)0);

die komplette Fehlermeldung ist etwas hardcore und im Anhang.
Wie kann ich dem Compiler helfen die richtige Funktion zu finden wenn es 
überladene gibt?

von Oliver S. (oliverso)


Lesenswert?

Ich tippe mal darauf, daß die Fehlermeldung hier das Problem beschreibt:

> have incompatible cv-qualifiers

Oliver

von J. S. (jojos)


Lesenswert?

Danke,
Aber je mehr ich mir das anschaue bin ich sicher das die beiden 
Funktionen nicht unterschieden werden können. Beide passen mit den 
varargs und der Compiler kann nicht wissen welche mir lieber ist.
Da hätte ich nur erwartet das eine Fehlermeldung mit ambiguous irgendwas 
kommt.

von Oliver S. (oliverso)


Lesenswert?

J. S. schrieb:
> Aber je mehr ich mir das anschaue bin ich sicher das die beiden
> Funktionen nicht unterschieden werden können. Beide passen mit den
> varargs und der Compiler kann nicht wissen welche mir lieber ist.

Doch, kann er. Daran liegt es nicht. Da ist ein const qualifier Problem.

Oliver

von J. S. (jojos)


Lesenswert?

Wenn ich die nicht benutzte Funktion mit bool Argument auskommentiere 
dann funktioniert es ja.
Bei diesem call musste ich auch die uint8_t typecasts angeben, sonst 
ging es auch nicht. Aber es bedeutet das dieser call passt.

Der Compiler versucht die Überladungen von EventQueue.call() aufzulösen, 
die cv-qualifiers passen nicht bei den Versionen mit const volatile. Das 
ist ja auch keine Fehlermeldungen, sondern die notes mit denen der 
Compiler versucht hat das aufzulösen.

: Bearbeitet durch User
von Rolf M. (rmagnus)


Lesenswert?

J. S. schrieb:
> Es funktioniert nur wenn es nur eine LEDControl() Funktion gibt, sonst
> scheint der Compiler das nicht auflösen zu können.

Erwartest du, dass er aus der Anzahl der an ein variadisches Template 
übergebenen Argumente und einem Aufruf innerhalb des Templates erkennt, 
welche Funktion du meinst? Ich denke nicht, dass er das tut.

J. S. schrieb:
> Wie kann ich dem Compiler helfen die richtige Funktion zu finden wenn es
> überladene gibt?

Wenn der Compiler es nicht selbstständig auflösen kann, musst du 
explizit  angeben, welche du meinst. Das wird über die Cast-Syntax 
gemacht, etwa so:
1
queue.call(&finger, static_cast<void(Adafruit_Fingerprint::*)(uint8_t, uint8_t, uint8_t, uint8_t)>(&Adafruit_Fingerprint::LEDcontrol), (uint8_t)FINGERPRINT_LED_ON, (uint8_t)0, (uint8_t)FINGERPRINT_LED_BLUE, (uint8_t)0);
Und ja, die Syntax ist hässlich, lässt sich aber hinter einem Makro 
verstecken.

von J. S. (jojos)


Lesenswert?

Bingo und Danke, so funktioniert es (mit uint8_t statt void als return 
type).
Bis zum static_cast bin ich auch gerade gekommen, hatte da aber noch 
nicht die richtige Syntax hinbekommen.
Ja, ein typedef entzerrt das. So einen Ausdruck zu bauen ist die eine 
Sache, das zu verstehen wenn man es vorgesetzt bekommt eine andere...

Um die LED am Fingerprint Sensor ein und auszuschalten, für die Puristen 
hier :)
1
  // fingerprint detect action
2
  wakeupFP.fall( []() {
3
    queue.call(&finger, static_cast<uint8_t(Adafruit_Fingerprint::*)(uint8_t, uint8_t, uint8_t, uint8_t)>(&Adafruit_Fingerprint::LEDcontrol), 
4
      (uint8_t)FINGERPRINT_LED_ON, (uint8_t)0, (uint8_t)FINGERPRINT_LED_BLUE, (uint8_t)0);
5
  });
6
7
8
  // fingerprint release action
9
  wakeupFP.rise( []() {
10
    queue.call(&finger, static_cast<uint8_t(Adafruit_Fingerprint::*)(uint8_t, uint8_t, uint8_t, uint8_t)>(&Adafruit_Fingerprint::LEDcontrol), 
11
      (uint8_t)FINGERPRINT_LED_OFF, (uint8_t)0, (uint8_t)FINGERPRINT_LED_BLUE, (uint8_t)0);
12
  });

: Bearbeitet durch User
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.