passing function as argument in c++ - c++

I am trying pass the function as an argument, the Testabc is inherited from MainTest and the function I want to pass is protected function in MainTest class. I do not have the cpp access to the MainTest class which has this protected ReadTestPoint function.
Below is header file where I define the function that is taking the function as an argument.
#include <QObject>
#include <QDebug>
class TestManager
{
public:
TestManager();
~TestManager() {}
int ReadTestPointer(void *dp, unsigned int &val, int (*functioncall)(void *,
unsigned int&));
};
Below is the cpp for the TestManager
#include "testmanager.h"
#include<QDebug>
TestManager::TestManager(){}
int TestManager::ReadTestPointer(void* dp, unsigned int &num, int (*readt)
(void*, unsigned int&))
{
qDebug()<< "Function Pointer working";
int g;
g = (*readt)(dp, num);
return g;
}
The class from where I am making the call:
namespace PackageCore
{
TestAbc::TestAbc() : MainTest(){}
TestAbc::~TestAbc(){}
int TestAbc::Init()
{
// initialization code called once
m_config = reinterpret_cast<Test_BaseClass*>
(GetConfig(Test_BaseClass_INTERFACE_HASH));
return 0;
}
int TestAbc::DeInit()
{
return 0;
}
int TestAbc::Cycle()
{
TestManager m_TestManager;
unsigned int m_trigger;
int (*abc)(void *, unsigned int&) = ReadTestPoint(m_config-
>SHM_B_Trigger_U8, m_trigger);
m_TestManager.ReadTestPointer(m_config->SHM_B_Trigger_U8, m_trigger, abc);
qDebug()<< " getTrigger: " << m_trigger;
return 0;
}
}
But I get the compile time error on this:
C:\test_manager_git\testabc.cpp:39: error: invalid conversion from 'int' to 'int (*)(void*, unsigned int&)' [-fpermissive]
int (*abc)(void *, unsigned int&) = ReadTestPoint(m_config->SHM_B_Trigger_U8, m_trigger);
The MainTest.h is below:
class MainTest : public QObject
{
Q_OBJECT
public:
// Callbacks
virtual int Init() = 0;
virtual int Cycle() = 0;
virtual int DeInit() = 0;
protected:
int ReadTestPoint (void *dp, unsigned int &val);
};
Thanks

First of all, consider using things like std::function instead of rolling your own pointer nightmare. But lets get started...
Basically, in order to call a member function from pointer, you need the function pointer and a member instance. The following code is based on your question code with the added member pointer.
#include <iostream>
class MainTest
{
public:
protected:
int ReadTestPoint (void *dp, unsigned int &val)
{
std::cout << "protected ReadTestPoint called" << std::endl;
return 0;
}
};
class TestManager
{
public:
TestManager() {}
~TestManager() {}
int ReadTestPointer(void *dp, unsigned int &val, MainTest* instance, int (MainTest::*functioncall)(void *, unsigned int&))
{
return (instance->*functioncall)(dp, val);
}
};
class TestAbc : public MainTest
{
public:
void ExecTest()
{
TestManager testManager;
unsigned int tVal;
void* dummy = &tVal;
testManager.ReadTestPointer(dummy, tVal, this, &TestAbc::ReadTestPoint);
}
};
int main(void)
{
TestAbc test;
test.ExecTest();
return 0;
}
If you don't want to restrict yourself to a specific member type, consider using a template function:
class TestManager
{
public:
TestManager() {}
~TestManager() {}
template<typename Fn>
int ReadTestPointer(void *dp, unsigned int &val, Fn functioncall)
{
return functioncall(dp, val);
}
};
It will accept non-member functions and objects that overload the operator() with appropriate parameters and return types.
You can wrap the member function pointer in a Functor object:
template<typename TMember, typename TResult, typename TParam1, typename TParam2>
struct Functor
{
typedef TResult (TMember::*TFn)(TParam1, TParam2);
Functor(TMember* m, TFn func):member(m), fn(func){}
TMember* member;
TFn fn;
TResult operator()(TParam1 p1, TParam2 p2)
{
return (member->*fn)(p1, p2);
}
};
The following example includes a free function call and a member function call:
int FreeFn(void *dp, unsigned int &val)
{
std::cout << "free function called" << std::endl;
return 1;
}
class TestAbc : public MainTest
{
public:
void ExecTest()
{
TestManager testManager;
unsigned int tVal;
void* dummy = &tVal;
testManager.ReadTestPointer(dummy, tVal, Functor<TestAbc, int, void*, unsigned int&>(this, &TestAbc::ReadTestPoint));
testManager.ReadTestPointer(dummy, tVal, FreeFn);
}
};

Related

How to assign the functor via an interface to a function object?

I have an interface and a class that implements it. Consider following code:
#include <functional>
using namespace std;
class Interface {
public:
virtual bool operator()() = 0;
};
class Derived : public Interface {
public:
bool operator()() override {
//some code here
return true;
};
};
int main() {
Derived d;
function<bool()> bar = d; //compiles without any errors
Interface* i = new Derived();
function<bool()> foo = *i; //does not work
return 0;
}
The compiler returns error C2440: 'initializing': cannot convert from 'Interface' to 'std::function'. How can I assign the functor via an interface to a function object?
EDIT: Thanks for the suggestions. Using std::bind helped but I still have a problem when I want to pass a parameter in the operator() function. See the following code:
#include <functional>
#include <iostream>
using namespace std;
class Interface {
public:
virtual bool operator()(unsigned int) = 0;
};
class Derived : public Interface {
public:
bool operator()(unsigned int count) override {
for (unsigned int i = 0; i < count; i++) {
cout << "Hello World \n";
}
return true;
};
};
bool doSomething(function<bool(unsigned int)> const& predicate) {
if (predicate(5)) {
return true;
}
};
int main() {
Derived d;
doSomething(d); //works
Interface* i = new Derived();
doSomething(std::bind(&Interface::operator(), i)); //does not compile
return 0;
}
I get the compiler error C2664:
'bool doSomething(const std::function &)': cannot
convert argument 1 from 'std::_Binder' to 'const
std::function &'
Any ideas?
The line function<bool()> foo = *i; is attempting to slice your Derived instance to a Instance (due to assignment operator on std::function), which can't happen because it's an abstract class. You can use a lambda to bind your function:
function<bool()> bar = [&]() { d(); };
Having read your comment:
I have a different class that expects a function object and i wanted to provide it via a functor of a class
You could do something like this:
void Foo::Bar(Instance &instance)
{
// Be careful of lifetime issues, depending on lifetime of stored function
std::function<bool ()> func = [&]() { instance(); };
// Do something with func
}
After question edit.
class Interface {
public:
virtual bool operator()(unsigned int) = 0;
};
operator() now has one parameter of type unsigned int, but a functional object returned by std::bind takes zero.
Possible solutions:
doSomething(std::bind(&Interface::operator(), i, std::placeholders::_1));
// or
doSomething([=](auto... args) { return (*i)(args...); });
// or
doSomething([=](auto... args) { return std::invoke(*i, args...); });

Initialize static function pointer in constructor

I am trying to declare a class-member function pointer as static so it can be called by a static member function, and assign the pointer to a function passed to the constructor.
So far I haven't been able to get it working, is this somehow possible?
#include <stdio.h>
//external callback function
static void innerFunc(int i, float f){
printf("running inner function : %i %f\n", i, f);
}
class A{
// member function pointer
typedef void (A::*cbPtr)(int, float);
static cbPtr cbptr;
public:
//constructor
A(void(*func)(int, float))
{
A::cbptr = func; // < this doesn't work
}
void run()
{
memberFunc(5, 4.4, NULL, NULL);
}
private:
// static member function
static void memberFunc(int i, float f, void* a, const void* aa)
{
printf("running outer function.\n");
// cbptr(i, f); // << I want to be able to call the function here
}
};
int main() {
A a(innerFunc);
a.run();
return 0;
}
The A::cbPtr type expects a pointer to a non-static member function of the A class. But you are trying to assign a pointer to a non-member function to your static cbptr variable. They are two different types, that is why the code does not compile.
Drop the A:: from your cbPtr typedef, eg:
#include <stdio.h>
//external callback function
static void innerFunc(int i, float f)
{
printf("running inner function : %i %f\n", i, f);
}
class A
{
public:
// non-member function pointer
typedef void (*cbPtr)(int, float);
//constructor
A(cbPtr func)
{
m_cbptr = func;
}
void run()
{
memberFunc(5, 4.4, NULL, NULL);
}
private:
static cbPtr m_cbptr;
// static member function
static void memberFunc(int i, float f, void* a, const void* aa)
{
printf("running outer function.\n");
m_cbptr(i, f);
}
};
A::cbPtr A::m_cbptr = NULL;
int main()
{
A a(innerFunc);
a.run();
return 0;
}
When you learn how to separate your declarations and definitions into .h and .cpp files, it would look more like this instead:
A.h:
#ifndef A_H
#define A_H
class A
{
public:
// non-member function pointer
typedef void (*cbPtr)(int, float);
//constructor
A(cbPtr func);
void run();
private:
static cbPtr m_cbptr;
// static member function
static void memberFunc(int i, float f, void* a, const void* aa);
};
#endif
A.cpp:
#include "A.h"
#include <stdio.h>
A::cbPtr A::m_cbptr = NULL;
A::A(A::cbPtr func)
{
m_cbptr = func;
}
void A::run()
{
memberFunc(5, 4.4, NULL, NULL);
}
void A::memberFunc(int i, float f, void* a, const void* aa)
{
printf("running outer function.\n");
m_cbptr(i, f);
}
main.cpp:
#include "A.h"
#include <stdio.h>
//external callback function
static void innerFunc(int i, float f)
{
printf("running inner function : %i %f\n", i, f);
}
int main()
{
A a(innerFunc);
a.run();
return 0;
}
Either way, just know that because m_cbptr is static, multiple instances of A will share the same variable, so you won't be able to have separate callbacks for different A objects. If memberFunc() were not static, or if its a or aa parameter is a user-defined value that can be set to point at the A object's this pointer, then you can have a separate callback per object.

Assign a function pointer using template method?

consider the Utility class below:
It will contain lots of factory methods with same signature int function(int a, int b);
Utility.h
class Utility
{
public:
template<typename T, typename A, typename B>
static int get_function(T% function, int% number)
{
function = (T) add;
number = 10;
return 0;
}
static int add (int a, int b) {
return a+b;
}
};
this contains a template method (get_function()) to assign Function pointers from factory methods available in Utility class.
Main.cpp
typedef int (__stdcall *FP) (int a, int b);
ref class FPClass
{
public:
static FP fp;
static int number;
static void apply_function()
{
Utility::get_function<FP, int, int>(FPClass::fp, number);
cout << FPClass::fp(25, 45);
}
};
void main()
{
FPClass::apply_function();
}
What I want to achieve is, to assign the function pointer (FPClass::fp) by the template method (Utility:get_function).
But the function pointer parameter is not modified (always null) by the called function (Utility:get_function).
why is that?

C++ template design with function pointers

Im bit new to c++, please let me describe my problem. I have a class called CSubcriber, which main purpose is to execute some callback function, of some type and some number of arguments. For example callbacks can be:
typedef void (*cb1)(void)
typedef int (*cb2)(int, int)
typedef char (*cb3)(int, int, void);
class itself is:
template <class CallbackType>
class CSubscriber {
public:
CSubscriber();
virtual ~CSubscriber();
CallbackType (*m_callback_newWay)(void *params);
void (*m_callback)(void *params);
int (*m_callback_int)(void *params);
void *m_cb_params;
int execute_cb();
void *m_params;
CSubscriber(void (*callback)(void *params), void *cb_params);
CSubscriber(int (*callback)(void *params), void *cb_params);
};
CSubscriber::CSubscriber(void (*callback)(void *params), void *cb_params){
m_callback = callback;
m_cb_params = cb_params;
}
CSubscriber::CSubscriber(int (*callback)(void *params), void *cb_params){
m_callback_int = callback;
m_cb_params = cb_params;
}
My main problem is now, how to write constructor, which will handle with all that variable arguments to callback. After constructing object in some particular moment, callback may be fired, for example:
typedef int (*callback)(void *params);
CSubscriber s(callback, params);
or
typedef void (*callback2)(void *params, int arr, char *ptr);
CSubscriber s(callback, params, arr, ptr);
Now, calling
s->m_callback()
I want to execute callback with all arguments which i passed for constructor.
I'd like to avoid writing ten different constructors, for each different number of arguments passed to callback function. Is it possible to do ?
Try something like this.
#include <iostream>
using namespace std;
typedef void (*cb1)(void);
typedef int (*cb2)(int, int);
typedef char (*cb3)(int, int, char);
template <class CallbackType>
class CSubscriber
{
public:
CSubscriber(): fcn1(0), fcn2(0), fcn3(0) {};
virtual ~CSubscriber(){};
CSubscriber(cb1 fcn): fcn1(fcn), fcn2(0), fcn3(0), a(), b() {};
CSubscriber(cb2 fcn, int p1, int p2): fcn1(0), fcn2(fcn), fcn3(0), a(p1), b(p2) {};
int execute_cb() {
if ( fcn1 != 0 ) {
(*fcn1)();
}
if ( fcn2 != 0 ) {
(*fcn2)(a,b);
}
};
protected:
cb1 fcn1;
cb2 fcn2;
cb3 fcn3;
int a, b;
};
void fcn1() {
cout << "in fcn1" << endl;
};
int fcn2(int a, int b) {
cout << "in fcn2, a " << a << ", b " << b << endl;
};
int main()
{
CSubscriber<int> cs;
CSubscriber<int> cs1(&fcn1);
CSubscriber<int> cs2(&fcn2, 1, 100);
cs.execute_cb();
cs1.execute_cb();
cs2.execute_cb();
}

Call different versions of template member function based on template paramaters

I need to call different versions of a template member function with the same arguments based on certain static members of the template parameters. Here's a sort of simplified version of what I need to do:
class A {
public:
//...
static const char fooString[];
};
const char A::fooString[] = "This is a Foo.";
class B {
public:
//...
static const char barString[];
};
const char B::barString[] = "This is a Bar.";
class C {
public:
//...
static const char fooString[];
};
const char C::fooString[] = "This is also a Foo.";
//Many other classes which have either a fooString or a barString
void doFoo(const char*s) { /*something*/ }
void doBar(const char*s) { /*something else*/ }
template&ltclass T>
class Something {
public:
//This version should be called if T has a static member called "fooString",
//so it should be called if T is either class A or C
void doSomething() { doFoo(T::fooString); }
//This version should be called if T has a static member called "barString",
//so it should be called if T is class B
void doSomething() { doBar(T::barString); }
};
void someFunc()
{
Something&ltA> a;
Something&ltB> b;
Something&ltC> c;
a.doSomething(); //should call doFoo(A::fooString)
b.doSomething(); //should call doBar(B::barString)
c.doSomething(); //should call doFoo(C::fooString)
}
How would I achieve this?
A possible solution:
#include <iostream>
#include <type_traits>
class A {
public:
//...
static const char fooString[];
};
const char A::fooString[] = "This is a Foo.";
class B {
public:
//...
static const char barString[];
};
const char B::barString[] = "This is a Bar.";
class C {
public:
//...
static const char fooString[];
};
const char C::fooString[] = "This is also a Foo.";
void doFoo(const char*s) { std::cout << "doFoo: " << s << "\n"; }
void doBar(const char*s) { std::cout << "doBar: " << s << "\n"; }
template<class T>
class Something {
public:
//This version should be called if T has a static member called "fooString",
//so it should be called if T is either class A or C
template <typename TT = T, typename std::enable_if<TT::fooString != 0, bool>::type = false>
void doSomething() { doFoo(T::fooString); }
//This version should be called if T has a static member called "barString",
//so it should be called if T is class B
template <typename TT = T, typename std::enable_if<TT::barString != 0, bool>::type = false>
void doSomething() { doBar(T::barString); }
};
int main()
{
Something<A> a;
Something<B> b;
Something<C> c;
a.doSomething(); //should call doFoo(A::fooString)
b.doSomething(); //should call doBar(B::barString)
c.doSomething(); //should call doFoo(C::fooString)
}
Output:
doFoo: This is a Foo.
doBar: This is a Bar.
doFoo: This is also a Foo.