c++: no matching function for call to ... <unresolved overloaded function type>

Seite 1 von 1 - Forum: Coding Stuff auf overclockers.at

URL: https://www.overclockers.at/coding-stuff/c-no-matching-function-for-call-to-unresolved-overloaded-function-type_240204/page_1 - zur Vollversion wechseln!


wergor schrieb am 01.09.2014 um 21:30

ich programmiere gerade meinen arduino, und benutze dafür die accelstepper library. die hat einen konstruktor, der wie folgt ausschaut:

Code: CPP
    /// Alternate Constructor which will call your own functions for forward and backward steps. 
    /// You can have multiple simultaneous steppers, all moving
    /// at different speeds and accelerations, provided you call their run()
    /// functions at frequent enough intervals. Current Position is set to 0, target
    /// position is set to 0. MaxSpeed and Acceleration default to 1.0.
    /// Any motor initialization should happen before hand, no pins are used or initialized.
    /// \param[in] forward void-returning procedure that will make a forward step
    /// \param[in] backward void-returning procedure that will make a backward step
    AccelStepper(void (*forward)(), void (*backward)());
der wird so aufgerufen:
Code: CPP
AccelStepper stepper1(forwardstep1, backwardstep1);
wobei die beiden parameter folgende funktionen sind:
Code: CPP
// you can change these to SINGLE or DOUBLE or INTERLEAVE or MICROSTEP!
// wrappers for the first motor!
void forwardstep1() {
  AFstepper1->onestep(FORWARD, stepType1);
}
void backwardstep1() {
  AFstepper1->onestep(BACKWARD, stepType1);
}
das funktioniert auch wunderbar, solange alles in dem main sketch liegt. jetzt habe ich mir eine klasse gebaut:
.h file
Code: CPP
//Filter Wheel

#ifndef FILTERWHEEL_H_INCLUDED
#define FILTERWHEEL_H_INCLUDED
#endif

#include "Device.h"
#include <Wire.h>
#include <Adafruit_MotorShield.h>
#include <AccelStepper.h>

#define IICADDRESS 0x60

class FilterWheel : public Device
{
public:
	//blabla
	FilterWheel();
private:
	//Adafruit Motor Shield object
	Adafruit_MotorShield AFMS; 
	//Adafruit Stepper Motor object
	Adafruit_StepperMotor *AFstepper;
	//AccelStepper wrapper
	AccelStepper stepper;

	void forwardstep();
	void backwardstep();

	float gearRatio;
	int numberOfFilters;
	uint8_t stepType;
};
.cpp file:
Code: CPP
//Filter Wheel

#include "FilterWheel.h"

//constructor
FilterWheel::FilterWheel()
{
	Adafruit_MotorShield AFMS (IICADDRESS);
	Adafruit_StepperMotor *AFstepper = AFMS.getStepper(200, 1); //M1 M2
	AccelStepper stepper(forwardstep, backwardstep);
}

//make 1 step forward
void FilterWheel::forwardstep() {
	AFstepper->onestep(FORWARD, stepType);
}
//make 1 step backward
void FilterWheel::backwardstep() {
	AFstepper->onestep(BACKWARD, stepType);
}
in der .cpp file, zeile 10 wirft mit der compiler folgende fehlermeldung (egal ob die beiden funktionen public oder private sind):
Code:
FilterWheel.cpp:In constructor 'FilterWheel::FilterWheel()'
FilterWheel.cpp:10: error: no matching function for call to 'AccelStepper::AccelStepper(<unresolved overloaded function type>, <unresolved overloaded function type>)'
AccelStepper.h:AccelStepper(void (*)(), void (*)())
AccelStepper.h:AccelStepper(uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, bool)
AccelStepper.h:AccelStepper(const AccelStepper&)
Error compiling
weis jemand wie ich das problem lösen kann? wenn ich die zeile auskommentiere kompiliert der code problemlos.
ersetze ich die zeile durch
Code: CPP
AccelStepper stepper(&forwardstep, &backwardstep);
gehts auch nicht:
Code:
FilterWheel.cpp:In constructor 'FilterWheel::FilterWheel()'
FilterWheel.cpp:10: error: ISO C++ forbids taking the address of an unqualified or parenthesized non-static member function to form a pointer to member function.  Say '&FilterWheel::forwardstep'
FilterWheel.cpp:10: error: ISO C++ forbids taking the address of an unqualified or parenthesized non-static member function to form a pointer to member function.  Say '&FilterWheel::backwardstep'
FilterWheel.cpp:10: error: no matching function for call to 'AccelStepper::AccelStepper(void (FilterWheel::*)(), void (FilterWheel::*)())'
AccelStepper.h:AccelStepper(void (*)(), void (*)())
AccelStepper.h:AccelStepper(uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, bool)
AccelStepper.h:AccelStepper(const AccelStepper&)
Error compiling
die klasse Device ist eine leere klasse, hat (noch) keine funktionen oder variablen.
bin für jede hilfe dankbar :)


Nico schrieb am 01.09.2014 um 21:44

mit funktions-zeigern kennst du dich aus?
http://www.cprogramming.com/tutoria...n-pointers.html


wergor schrieb am 01.09.2014 um 23:22

nein. hab mich jetzt ein bisschen damit herumgespielt,aber weiter als bis zu

Code:
FilterWheel.cpp:In constructor 'FilterWheel::FilterWheel()'
FilterWheel.cpp:8: error: cannot convert 'void (FilterWheel::*)()' to 'void (*)()' in assignment
FilterWheel.cpp:9: error: cannot convert 'void (FilterWheel::*)()' to 'void (*)()' in assignment
Error compiling
bin ich noch nicht gekommen.

edit:
.h file
Code: CPP
//Filter Wheel

#ifndef FILTERWHEEL_H_INCLUDED
#define FILTERWHEEL_H_INCLUDED
#endif

#include "Device.h"
#include <Wire.h>
#include <Adafruit_MotorShield.h>
#include <AccelStepper.h>

#define IICADDRESS 0x60

class FilterWheel : public Device
{
public:
	//blabla
	FilterWheel();

	void forwardstep();
	void (*fwdstp)();
	void backwardstep();
	void(*bckwdstp)();
private:
	//Adafruit Motor Shield object
	Adafruit_MotorShield AFMS; 
	//Adafruit Stepper Motor object
	Adafruit_StepperMotor *AFstepper; 
	//AccelStepper wrapper
	AccelStepper stepper; 


	float gearRatio;
	int numberOfFilters;
	uint8_t stepType;
};
.cpp file:
Code: CPP
//Filter Wheel

#include "FilterWheel.h"

//constructor
FilterWheel::FilterWheel()
{
	fwdstp = &FilterWheel::forwardstep;
	bckwdstp = &FilterWheel::backwardstep;
	
	Adafruit_MotorShield AFMS (IICADDRESS);
	Adafruit_StepperMotor *AFstepper = AFMS.getStepper(200, 1); //M1 M2
	AccelStepper stepper(fwdstp, bckwdstp);
}

//make 1 step forward
void FilterWheel::forwardstep() {
	AFstepper->onestep(FORWARD, stepType);
}
//make 1 step backward
void FilterWheel::backwardstep() {
	AFstepper->onestep(BACKWARD, stepType);
}
ergibt
Code:
FilterWheel.cpp:In constructor 'FilterWheel::FilterWheel()'
FilterWheel.cpp:8: error: cannot convert 'void (FilterWheel::*)()' to 'void (*)()' in assignment
FilterWheel.cpp:9: error: cannot convert 'void (FilterWheel::*)()' to 'void (*)()' in assignment
Error compiling

in der .cpp, zeile 8&9 beim = zeigt visual studio folgenden fehler:
vs_196656.png
ideen? :(


Ringding schrieb am 02.09.2014 um 15:27

Z.B. http://stackoverflow.com/questions/...n-as-a-callback


wergor schrieb am 03.09.2014 um 01:00

Zitat von Ringding
Z.B. http://stackoverflow.com/questions/...n-as-a-callback
danke für den link, leider hilft er mir überhaupt nicht :(
ich habe die letzten paar stunden recherchiert und versucht, die funktion bind() bei mir einzubauen. das includen der bind.hpp der (normalen) boost library alleine hat >2000 zeilen an fehlermeldungen verursacht. boost for arduino hat die funktion bind nicht, nur bind1st und bind2nd, die aber beide nicht funktionieren:
Code: CPP
bind1st(&FilterWheel::forwardstep, this);
Code:
functional:In instantiation of 'std::binder1st<void (FilterWheel::*)()>'
FilterWheel.cpp:instantiated from here
functional:*)()' is not a class, struct, or union type
functional:*)()' is not a class, struct, or union type
functional:*)()' is not a class, struct, or union type
functional:*)()' is not a class, struct, or union type
functional:In function 'std::binder1st<Operation> std::bind1st(const Operation&, const T&) [with Operation = void (FilterWheel::*)(), T = FilterWheel*]'
FilterWheel.cpp:instantiated from here
functional:*)()' is not a class, struct, or union type
Error compiling
wobei ich aber gar nicht weis ob ich die funktion richtig aufrufe, oder ob die für meinen zweck geeignet ist. hier eine doku.


PuhBär schrieb am 03.09.2014 um 03:25

Schau dir mal "mem_fun" an:

http://www.cplusplus.com/reference/functional/mem_fun/

Code: CPP
AccelStepper stepper(mem_fun(&FilterWheel::forwardstep), mem_fun(&FilterWheel::backwardstep));

Hat glaube ich eine Chance, dass es kompiliert. Bin aber schon ein wenig müde; vielleicht übersehe ich ja was.

Bei "bind1st" und "bind2nd" hast du ja das Problem, dass deine 2 Memberfunctions komplett ohne Parameter aufgerufen werden müssen. "bind1st" ruft den function call operator () immer mit 1, "bind2nd" immer mit 2 Argumenten auf.

Meh, "mem_fun" geht natürlich auch nicht, da wird ja automatisch der this pointer als Argument mitübergeben.


wergor schrieb am 03.09.2014 um 08:37

Zitat von wergor
danke für den link, leider hilft er mir überhaupt nicht :(
Ich war anscheinend ein bisschen voreilig, ich muss mir das nochmal anschauen.
mem_fun hab ich auch kurz probiert, war aber auch noch nicht erfolgreich

edit: das hier schaut nach einer möglichweise brauchbaren lösung für mein problem aus. wenn nur bind gehen würde :(
mem_fun produziert bei mir "interessante" fehlermeldungen, kommt daher das suffix _fun? :D

ich habe mich auch mit dem autor der library unterhalten aber er hat mir da auch nicht wirklich helfen können. mein thread auf stackoverflow hat bisher auch keine lösung gebracht.


Ringding schrieb am 04.09.2014 um 19:53

Wie in dem letzten Stackoverflow-Link (EDIT: Den mit "demote boost::function" meine ich) beschrieben, kann es nicht wirklich gehen. Normalerweise bekommen solche Callbacks ein void * übergeben, das man durchreichen kann. In diesem Fall ist das nicht der Fall, daher bleibt nur die Möglichkeit, die Objektinstanz in einer globalen Variable abzulegen:

Code: CPP
#include <iostream>

using std::cout;
using std::endl;

struct AccelStepper {
    AccelStepper(void (*forward)(), void (*backward)()):
        forward(forward),
        backward(backward)
    { }
    enum Direction { FORWARD, BACKWARD };
    void oneStep(Direction);
private:
    void (*forward)();
    void (*backward)();
};

void AccelStepper::oneStep(Direction dir)
{
    switch (dir) {
    case FORWARD:
        forward();
        break;
    case BACKWARD:
        backward();
        break;
    }
}

struct FilterWheel {
    void forward() { cout << "forward" << endl; }
    void backward() { cout << "backward" << endl; }
};

static FilterWheel *the_wheel;

static void fwd_trampoline()
{
    the_wheel->forward();
}

static void bckwd_trampoline()
{
    the_wheel->backward();
}

int main()
{
    FilterWheel wheel;
    the_wheel = &wheel;

    AccelStepper stepper(fwd_trampoline, bckwd_trampoline);
    stepper.oneStep(AccelStepper::FORWARD);
    stepper.oneStep(AccelStepper::BACKWARD);
    return 0;
}




overclockers.at v4.thecommunity
© all rights reserved by overclockers.at 2000-2025