Pass member function as argument - c++

I have a function that runs a callback:
void run_callback(void(*callback)(uint32_t)) {
callback(100);
}
This works with static functions,
void global_callback(uint32_t);
int main() {
run_callback(global_callback);
}
but not with member functions.
class A {
int x;
public:
void callback(uint32_t);
};
int main() {
A foo;
run_callback(foo.callback);
}
I work around this with a static wrapper function.
void run_member_callback(void* obj, void(*callback)(void*,uint32_t)) {
callback(obj, 100);
}
class B {
int x;
public:
static void static_callback(void* obj, uint32_t value) {
static_cast<B*>(obj)->callback(value);
}
void callback(uint32_t);
};
int main() {
B foo;
run_member_callback(&foo, foo.static_callback);
}
Is there a simple way to pass a member function as an argument?
edit:
I'm trying to avoid STL, and templates aren't an option since my implementation of run_callback is virtual.

You are doing some weird, C-ish things. Use C++ features. I personally would use a template for run_callback and a lambda for passing the member function:
template <class F>
void run_callback(F callback)
{
callback(100);
}
class A
{
int x;
public:
void callback(uint32_t);
};
int main()
{
A foo{};
run_callback([&](uint32_t a) { return foo.callback(a); });
}
If you capture the object by reference take care it outlives the run_callback call. Otherwise capture it by value.
What is a lambda expression in C++11?

Related

Default argument with template in C++

I'm designing an interface, by which users can define a class that tells what they want to do.
The code is something like the following,
#include <stdio.h>
class Dummy{
public:
void do(){ printf("do nothing\n"); }
};
class Task{
public:
void do(){ printf("do something\n"); }
};
template <class TASK>
void func(TASK &task = Dummy()){
task.do();
}
int main(){
func(); // do nothing
Task task;
func(task); // do something
}
How to make it work?
The main issue is this func argument:
TASK &task = Dummy()
It will not work unless it is const. This happens because non-const lvalue reference to type cannot bind to a temporary.
But if you can use const there, you can easily solve your problem:
class Dummy{
public:
void doit() const { printf("do nothing\n"); }
};
class Task{
public:
void doit() const { printf("do something\n"); }
};
template <class TASK = Dummy>
void func(const TASK &task = TASK()){
task.doit();
}
int main(){
func(); // do nothing
Task task;
func(task); // do something
}
For starters, don't have an identifier (function named) named do, since do is a language keyword. Using it as an identifier is a diagnosable error. There's no option other than changing the name of the function.
Second, the argument will of func() will need to be const, since the default value being passed is a temporary (which can only be bound to a const reference). This also means your function in the classes needs to be const qualified.
Third, when calling func() it is necessary to either pass SOME information so the compiler can work out how to instantiate the template. If you want to pass no information at all at the call site (i.e. func()) then you need to have a non-templated overload.
Fourth, use C++ streams rather than C I/O.
class Dummy
{
public:
void do_it() const { std::cout << "do nothing\n"; }
};
class Task
{
public:
void do_it() const { std::cout << "do something\n"; }
};
template <class TASK>
void func(const TASK &task)
{
task.do_it();
}
void func()
{
func(Dummy());
}
int main()
{
func(); // do nothing
Task task;
func(task); // do something
}
Option 2 is to replace the two versions of func() above with
template <class TASK = Dummy>
void func(const TASK &task = TASK())
{
task.do_it();
}

Type cast std::placeholder

I'm trying to use std::bind and typecast the function arguments to use with a typedef function. However, I can't typecast the std::placeholder. Any ideas to implement what I'm trying to do? For varied reasons, I need to be able to have the typedef function have a uint16_t argument, and also have the init function accept a member function that takes a uint8_t argument). The code (edited for simplicity) that I'm using:
typedef void (write_func_t) (uint16_t, uint8_t);
class MyClass {
public:
MyClass();
template < typename T >
void init(void (T::*write_func)(uint8_t, uint8_t), T *instance) {
using namespace std::placeholders;
_write_func = std::bind(write_func, instance, (uint16_t)_1, _2);
this->init();
}
private:
write_func_t *_write_func;
};
Wouldn't this be cleaner (and much simpler using lambdas and std::function<>)?
class MyClass {
using WriteFunc = std::function<void(int16_t, int8_t)>;
public:
void init(WriteFunc&& func) {
write_func_ = std::move(func);
}
private:
WriteFunc write_func_;
};
Then call in some other type..
class Foo {
// e.g
void SomeWriteFunction(int8_t x, int8_t y) {
}
void bar() {
// The lambda wraps the real write function and the type conversion
mc_inst.init([this](int16_t x, int8_t y) {
this->SomeWriteFunction(x, y);
});
}
};

Static templated member function as function pointer

I'm attempting to replace a series of static to non static member function pairs throughout my code, I can achieve this with a macro but I was hoping I could do so with a static function which takes the non static member function as a template argument, which then gets stored as a function pointer. See the following code:
struct widget_param
{
void* ptr;
};
struct widget_data
{
bool(*callback)(widget_param*);
};
template <class CLASSNAME>
class widget_base
{
protected:
static CLASSNAME* get_instance(widget_param* param)
{
return static_cast<CLASSNAME*>(param->ptr);
}
public:
template <bool(CLASSNAME::*f)(widget_param*)>
static bool static_to_nonstatic(widget_param* param)
{
return get_instance(param)->*f(param);
}
};
class widget_derived : public widget_base<widget_derived>
{
public:
// Attempting to replace this function
static bool static_do_stuff(widget_param* param)
{
return get_instance(param)->do_stuff(param);
}
bool do_stuff(widget_param* param)
{
param;
cout << "Success!";
return true;
}
};
int main() {
widget_derived derived;
//widget_data data{ widget_derived::static_do_stuff}; // Current approach
widget_data data{ widget_derived::static_to_nonstatic<widget_derived::do_stuff> };
widget_param param{ &derived };
data.callback(&param);
return 0;
}
I was expecting the template to evaluate to:
static bool static_to_nonstatic(widget_param* param);
Is it possible to do what I'm trying to achieve, without resorting to using a macro?
Resolved, since the call is to a member function pointer - it needed to be surrounded by parenthesis, changed the template to the following and it worked:
template <bool(CLASSNAME::*f)(widget_param*)>
static bool static_to_nonstatic(widget_param* param)
{
return (get_instance(param)->*f)(param);
}

Passing default parameter to function C++

I want to call function either with default arguments or given by me, but default arguments are specified class private variables, simplified sample here:
Class::Something
{
public:
void setI(int i);
private:
void func(int i = this->i_default, j=this, k=this->k_default, l=this->l_default);
int i_default; // May be different for different instances.
int k_default; // May be different for different instances.
int l_default; // May be different for different instances.
}
So when i call func() it takes default i_variable or when i call func(4) it takes 4 argument without changing i_default value.
I know im doing something wrong couse i get error:
Error 1 error C2355: 'this' : can only be referenced inside non-static member functions or non-static data member initializer
is there some kind of way to achive such behaviour?
is there some kind of way to achive such behaviour?
Use function overload (Thanks #PiotrSkotnicki):
void func(int i);
void func() { func(i_default); }
You can declare i_default as const static (Thanks to #TartanLama).
const static int i_default=1;
Here is the working program.
You can also use function overloading. But this uses less code than function overloading!
The standard is quite clear about this. You explicitely cannot use this in the default parameter. You seem to be bound to use overloading for achieving this result:
void func(int i);
void func() { func(i_default); }
If you want to keep down the functions you could use a sentry that would allow func decide if it's to use the default. In the simpliest form:
void func(int* pi = NULL) {
int i = pi ? *pi : i_default;
// rest of the function
}
This method could be extended to use a helper class:
#include <cstdio>
template <typename C, typename T>
class Defaltable {
T val;
T C::* ptr;
public:
Defaltable(int C::* p) {
ptr = p;
val = 0;
}
Defaltable(T x) {
val = x;
ptr = NULL;
}
T fetch(C* p) {
return ptr ? p->*ptr : val;
}
};
class Foo {
int i_default;
public:
Foo(int dflt) {
i_default = dflt;
}
int func(Defaltable<Foo, int> x = &Foo::i_default) {
return x.fetch(this);
}
};
int main()
{
Foo c(42);
printf("%d\n", c.func(1));
printf("%d\n", c.func());
}

How to write a general function callback test class?

I have several classes which each store and call a callback function. The callback functions' signatures have different parameter and return types, but all of them take just one parameter.
To verify that these classes call their callbacks when they should, I'm trying to write a general test class which (1) provides a callback function which takes one parameter, (2) lets the user query whether that function has been called, and (3) lets the user examine the parameter which was passed to that function. So far, I have something like this:
template<class ReturnType, class ParameterType> class Callable
{
public:
Callable() : m_called(false), m_param() {}
ReturnType operator()(ParameterType param)
{
m_called = true;
m_param = param;
return Returntype();
}
bool Called() { return m_called; }
ParameterType Param() { return m_param; }
private:
bool m_called;
ParameterType m_param;
};
Here's a class which might be tested using class Callable:
#include <boost/function.hpp>
class ToBeTested
{
ToBeTested(boost::function<bool (int)> callback) : m_callback(callback) {};
boost::function<bool (int)> m_callback;
// (methods which should cause the callback to be called here)
};
Here's some test code:
#include <boost/bind.hpp>
int main(int, char**)
{
Callable<bool, int> callable;
ToBeTested tbt(boost::bind(&Callable<bool, int>::operator());
// (tell tbt it should call its callback here)
if (callable.Called()
{
if (EXPECTED_VALUE == callable.Param();
return 0;
}
return -1;
}
This gives me (1) and (2), but there's a problem with (3) when the callback takes its parameter by reference: Callable::m_param is a reference type and therefore can't be default initialised. I could fix that by making Callable::operator() take its parameter by reference, like this:
ReturnType operator()(ParameterType & param)
...but then I can't use class Callable when the callback function takes its parameter by value.
Is there a way to make my test class work regardless of whether the callback function takes its parameter by reference, or do I need to write two nearly-identical test classes?
You could try something like this, where references are actually stored as pointers:
template<typename T>
struct ref_to_ptr
{
typedef T type;
static T wrap(T x) { return x; }
static T unwrap(T x) { return x; }
};
template<typename T>
struct ref_to_ptr<T&>
{
typedef T* type;
static T* wrap(T& x) { return &x; }
static T& unwrap(T* x) { return *x; }
};
template<class ReturnType, class ParameterType> class Callable
{
public:
Callable() : m_called(false), m_param() {}
ReturnType operator()(ParameterType param)
{
m_called = true;
m_param = ref_to_ptr<ParameterType>::wrap(param);
return Returntype();
}
bool Called() { return m_called; }
ParameterType Param() { return ref_to_ptr<ParameterType>::unwrap(m_param); }
private:
bool m_called;
typename ref_to_ptr<ParameterType>::type m_param;
};