"Christmas - the time to fix the computers of your loved ones" « Lord Wyrm

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

wergor 01.09.2014 - 21:30 4903 7
Posts

wergor

connoisseur de mimi
Avatar
Registered: Jul 2005
Location: graz
Posts: 4019
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

former person of interest
Registered: Sep 2006
Location: -
Posts: 4082
mit funktions-zeigern kennst du dich aus?
http://www.cprogramming.com/tutoria...n-pointers.html

wergor

connoisseur de mimi
Avatar
Registered: Jul 2005
Location: graz
Posts: 4019
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? :(
Bearbeitet von wergor am 01.09.2014, 23:58

Ringding

Pilot
Avatar
Registered: Jan 2002
Location: Perchtoldsdorf/W..
Posts: 4300

wergor

connoisseur de mimi
Avatar
Registered: Jul 2005
Location: graz
Posts: 4019
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

Schau ned so genau
Avatar
Registered: Sep 2002
Location: .
Posts: 1201
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.
Bearbeitet von PuhBär am 03.09.2014, 04:22

wergor

connoisseur de mimi
Avatar
Registered: Jul 2005
Location: graz
Posts: 4019
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.
Bearbeitet von wergor am 03.09.2014, 13:21

Ringding

Pilot
Avatar
Registered: Jan 2002
Location: Perchtoldsdorf/W..
Posts: 4300
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;
}
Bearbeitet von Ringding am 05.09.2014, 10:33
Kontakt | Unser Forum | Über overclockers.at | Impressum | Datenschutz