C++: Callback Funktion kann nicht aufgelöst werden

OP #7605345

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?

Angehängte Dateien:
OP #7605376

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.

OP #7605395

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.

#7605458

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.

OP #7605470

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
  });

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 2 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.