C++ 11 - bind a C style callback to a class member function - c++

Using code from http://ideone.com/5MHVz
I am curious how is it possible that I can bind a lambda function (inline) to a C style function pointer but I cannot do this with a class function even if there is no state involved. It must be some fundamental difference but I don't understand how lambda binding is possible in this case then (there is a conceptual this to lambda generated code also). Is there a workaround ?
Code bellow:
#include <iostream>
#include <functional>
using namespace std;
typedef int (*http_cb) (int*);
struct http_parser_settings {
http_cb on_message_begin;
};
class HttpParser
{
int OnMessageBegin(int* val){}
HttpParser()
{
http_parser_settings settings;
//settings.on_message_begin = std::bind(&HttpParser::OnMessageBegin, this, std::placeholders::_1); -- this one does not compile
settings.on_message_begin = [](int* p){ return 0;};
}
};
int main() {
}

Non-capturing lambdas can be converted to function pointers. They're essentially free functions, so there's no problem.

You can store lambdas in std::function objects even in MSVC2010, so there must be a way to get a raw function pointer. I've never delved into the details of how it works, but have certainly used this feature before.

Related

Question regarding the use of std::bind in ROS2 tutorial

I am fairly new to C++ and I have a question regarding practices of std::bind. The following snippet is copied from this tutorial on the ROS2 website. The code creates a class where the timer_ field hosts a timer that is created using create_wall_timer(). creates_wall_timer() accepts a callback object of type CallbackT &&. In the constructor of the class, why does the author pass the result of std::bind(...) as the callback to create_timer() instead of a direct pointer or reference to the timer_callback method?
Apologies for the long questions. I am not really good at asking these questions. Hopefully, I didn't miss too much information that you need.
#include <chrono>
#include <functional>
#include <memory>
#include <string>
#include "rclcpp/rclcpp.hpp"
#include "std_msgs/msg/string.hpp"
using namespace std::chrono_literals;
/* This example creates a subclass of Node and uses std::bind() to register a
* member function as a callback from the timer. */
class MinimalPublisher : public rclcpp::Node
{
public:
MinimalPublisher()
: Node("minimal_publisher"), count_(0)
{
publisher_ = this->create_publisher<std_msgs::msg::String>("topic", 10);
timer_ = this->create_wall_timer(
500ms, std::bind(&MinimalPublisher::timer_callback, this));
}
private:
void timer_callback()
{
auto message = std_msgs::msg::String();
message.data = "Hello, world! " + std::to_string(count_++);
RCLCPP_INFO(this->get_logger(), "Publishing: '%s'", message.data.c_str());
publisher_->publish(message);
}
rclcpp::TimerBase::SharedPtr timer_;
rclcpp::Publisher<std_msgs::msg::String>::SharedPtr publisher_;
size_t count_;
};
You can't pass a pointer to a member function in isolation (unless that function is declared static), because it needs an instance of the [right kind of] object to be called on.
std::bind binds a pointer to an object (this, in this example) to the member function pointer (&MinimalPublisher::timer_callback) so that when the time comes to call the function, there is an instance of the required / desired object available.
To look at this from another (simpler) angle, consider what happens if you write:
MinimalPublisher::timer_callback ();
If MinimalPublisher::timer_callback is not a static function the compiler will complain, because a non-static function can only be called through a [pointer to a] MinimalPublisher object, so something like:
my_minimal_publisher_object.MinimalPublisher::timer_callback ();
or:
my_minimal_publisher_object_pointer->MinimalPublisher::timer_callback ();
You might like to experiment with this in your favourite online compiler.
Incidentally, std::bind has been largely superseded by capturing lambdas these days. So, in order to capture the required object instance (and taking my original example over at Wandbox as a starting point), you might do:
#include <functional>
struct MyStruct
{
void foo ();
};
int main()
{
MyStruct s;
std::function <void ()> f = [&s] { s.foo (); };
// Do things with f
}

Passing a callback function pointer to a function in another class

I know questions like this have been asked, but none of the answers have helped me. Although I have coded some C++ in the past as needed I am not fluent by any stretch. Today, I am stuck trying to pass a callback function to a function in another class. Below is a short example:
#include "stdafx.h"
#include <functional>
class A
{
private:
int _someMemberVar = 7;
public:
void SomeFunction(std::function<void(int)> func)
{
func(_someMemberVar);
}
};
class B
{
public:
void DoSomeWork()
{
A a;
// error C2275: 'std::function<void (int)>' : illegal use of this type as an expression
a.SomeFunction(std::function<void(int)> &B::MyCallback);
}
void MyCallback(int i)
{
printf("parameter is %d\r\n", i);
}
};
int _tmain(int argc, _TCHAR* argv[])
{
B b;
b.DoSomeWork();
return 0;
}
I have tried the example code from this std::function documentation page, but it doesn't compile. I had similar issues with other examples I found, such as those in the dissertation here. I am using Visual Studio 2013.
Googling the various compiler errors hasn't helped me sort this out and I'm feeling frustrated and confused. About the only thing I know for sure is that we C# programmers sure are spoiled. Any help is greatly appreciated.
Edit: Thanks so much for all the help everyone. All the answers provided a working solution, and if I could green check them all I would. I went with the answer posted by super because it had the most explanation and seems closest to what I am porting. Thanks again all!
Apart from the missing brackets around &B::MyCallback (typo?) the main issue here is that a member function and a normal function are not the same thing.
A member function acts on an object, while a function does not, so a pointer to a member function can't just be converted to a normal function pointer.
The most straight forward solution in your case is to pass a lambda that captures this.
a.SomeFunction([&](int i){ MyCallback(i); });
The lambda will capture the current object and forward i as a parameter to the member function.
Logically, you need an object to call the callback function on. Here's one way to do it:
a.SomeFunction([this] (int const i) { MyCallback(i); });
Here's another way to do the same thing. Assuming that you don't want to change the method into a static method and you want to call the MyCallback method on this
using namespace std::placeholders;
std::function<void(int)> func = std::bind(&B::MyCallback, this, _1);
a.SomeFunction(func);

How to define a vector of functions that accepts different parameter types in c++?

I am doing a challenge for myself and writing a program in C++ without using classes and class related machinery. Additional conditions are I can use everything from stl and have full type safety, meaning no raw pointers or casting from one type to another. I am now in a situation where I'm not sure how to proceed with the constraints I have put on myself.
Problem: I want to create a std::vector of functions, but each of those functions might take a different data type, and operate on that type only. Example:
struct DataAndFunction {
AnyDataType data;
std::function<void(AnyDataType&)> functionOperatingWithData;
};
...
std::vector<DataAndFunction> listOfFunctions;
...
for(auto& dataAndFunc : listOfFunctions) {
dataAndFunc.functionOperatingWithData(dataAndFunc.data);
}
then there either would be different kind of AnyDataType and accompanying functions.
I know it could be solved in a couple of ways:
with classes using polymorphism, where
std::vector< DataAndFunction > listOfFunctions;
would just take a base class as a template parameter, and would have virtual method, that would be implemented by child classes, each with their own private data members, but the point of my challenge is to not use this pattern.
I could pass void* as data and function signature, and inside each function I would cast the data to the appropriate type, but I want to use type safety and only smart pointers
I could also make DataAndFunction struct a generic by adding template parameter, but then how do I make a vector that could be filled with not just with of DataAndFunction<int> for example, but any template parameter?
And how would this problem be solved in a more functional style? How would a functional solution look in C++ that would operate on a list of functions each taking a different type of argument? Without using inheritance of course.
Or am I just asking how to emulate a virtual table?
It seems you only need std::function<void()>:
DataAndFunction<int> dint;
DataAndFunction<char> dchar;
std::vector<std::function<void()>> funcs{
[&](){ dint.f(dint.data); },
[&](){ dchar.f(dchar.data); },
[](){ std::cout << "Hello world\n"; }
};
for (auto& f : funcs) {
f();
}
How you know, C++ is a strong typed language. That means you can't have a generic variable like others languages do like Python.
In C, the solution is to use a point to void (void*), but it is hard to manage and error-prone.
C++17 comes with 2 elegant solutions these you can use:
std::any and
std::variant.
This is one way you could store a vector of functions that take different types as parameters, it also accepts a varying amount of parameters. It uses std::any, std::pair, and std::tuple to contain the function and its parameter(s). std::any is much safer than a void * however there is more memory overhead as std::any stores quite a bit of data.
the program simply outputs : "Hello World!"
#include <any>
#include <tuple>
#include <string>
#include <vector>
#include <utility>
#include <iostream>
#include <functional>
std::vector<std::pair<std::function<void(const std::any&)>, std::any>> funcList;
template <typename F, typename...T>
std::size_t insertAnyFunc(const F &func, const T&...params) {
auto t = std::make_tuple<const T&...>(params...);
funcList.push_back({
[f = func](const std::any &a) {
if constexpr (sizeof...(T) == 0)
f();
else
std::apply(f, std::any_cast<const std::tuple<T...> &>(a));
}, std::make_any<std::tuple<T...>>(t)
});
return funcList.size();
}
void execAnyFunc(const std::size_t &ID) {
if (ID < funcList.size())
funcList.at(ID).first(funcList.at(ID).second);
}
int main (void) {
insertAnyFunc([](const std::string &s){ std::cout << s; }, std::string("Hello World!\n"));
execAnyFunc(0);
return 0;
}

Create a function from another one

more than a general case, I have a very specific example in mind : in GSL (GNU Scientific Library), the main function type used (in order to perform integration, root finding,...) is gsl_function , which have an attribute function whose type is double(*)(double, void *)
Say I want to create a gsl_function from double a_squared(double a) {return a*a};. a__squared 's type is double(*)(double) I would like to create a convert function taking in argument (double(*)(double) f) and returning an object of type double(*)(double, void *) which would satisfy convert(f)(double a, NULL) == f(a)
But after some research, it seems like I can't define another function in my convert function. How to proceed ?
The need to pass a raw function pointer to the GSL API limits your options considerably - you can't use anything based on std::function because there's no way to obtain a function pointer from a std::function (and this rules out lambdas using captures, which would have offered a neat solution).
Given these constraints, here's a possible solution making use of a static wrapper class. You could just as well have put the contents of this class in a namespace, but using the class at least gives some semblance of encapsulation.
typedef double gsl_function_type(double, void*); // typedef to make things a bit more readable...
// static class to wrap single-parameter function in GSL-compatible interface
// this really just serves as a namespace - there are no non-static members,
// but using a class lets us keep the details private
class Convert
{
Convert() = delete; // don't allow construction of this class
// pointer to the function to be invoked
static double (*m_target)(double);
// this is the function we'll actually pass to GSL - it has the required signature
static double target(double x, void*) {
return m_target(x); // invoke the currently wrapped function
}
public:
// here's your "convert" function
static gsl_function_type* convert(double (*fn)(double)) {
m_target = fn;
return &target;
}
};
There's a live example here: http://coliru.stacked-crooked.com/a/8accb5db47a0c51d
You're trapped by gsl's (poor) design choice of using C (instead of C++) to provide a C-style function pointer. Thus, you cannot use (C++ style) function-objects (functor), but must provide the pointer to a real function and one cannot generate a function in the same way one can genarate functors.
(Not recommended) You can use a global variable to store the actual function (a_squared) and then define a particular gsl_function that actually calls that global variable:
// from some gsl header:
extern "C" {
typedef double gsl_function(double, void*);
// calls func(arg,data_passed_to_func)
double gsl_api_function(gsl_function*func, void*data_passed_to_func);
}
// in your source code
double(*target_func)(double); // global variable can be hidden in some namespace
extern "C" {
double funtion_calling_target(double, void*)
}
double funtion_calling_target(double arg, void*)
{
return target_func(arg);
}
bool test(double x, double(*func)(double))
{
target_func = func;
return x < gsl_api_function(function_calling_target,0);
}
(hiding target_func as static member of some class as in atkins's answer still requires a global variable). This works, but is poor, since 1) this mechanism requires a global variable and 2) only allows one target function to be used a any time (which may be hard to ensure).
(Recommended) However, you can define a special function that takes another function pointer as argument and passes it as data element. This was in fact the idea behind the design of gsl_function: the void* can point to any auxiliary data that may be required by the function. Such data can be another function.
// your header
extern "C" {
double function_of_double(double, void*);
}
inline double function_of_double(double arg, void*func)
{
typedef double(*func_of_double)(double);
return reinterpret_cast<func_of_double>(func)(arg);
}
// your application
bool test(double x, double(*func)(double))
{
return x < gsl_api_function(function_of_double, (void*)(func));
}
This does not require a global variable and works with as many different simultaneous functions as you want. Of course, here you are messing around with void*, the very thing that every sensible C++ programmer abhors, but then you're using a horrible C library which is based on void* manipulations.
Thought I would add my lambda-based attempts at this.
It works fine in principle:
// function we want to pass to GSL
double a_squared(double a) { return a*a; }
typedef double gsl_function_type(double, void*); // convenient typedef
// lambda wrapping a_squared in the required interface: we can pass f directly to GSL
gsl_function_type* f = [](double x, void*) { return a_squared(x); };
But we'd really like to write a method to apply this to any given function. Something like this:
gsl_function_type* convert(double (*fn)(double))
{
// The lambda has to capture the function pointer, fn.
return [fn](double x, void*) { return fn(x); };
}
However, the lambda now has to capture the pointer fn, because fn has automatic storage duration (in contrast to the static function a_squared in the first example). This doesn't compile because a lambda which uses a capture cannot be converted to a simple function pointer, as required by the return value of our function. In order to be able to return this lambda we'd have to use a std::function, but there's no way to get a raw function pointer from that, so it's no use here.
So the only way I've managed to get this to work is by using a preprocessor macro:
#define convert(f) [](double x, void*) { return f(x); }
This then lets me write something like this:
#include <iostream>
using namespace std;
typedef double gsl_function_type(double, void*); // convenient typedef
// example GSL function call
double some_gsl_function(gsl_function_type* function)
{
return function(5.0, nullptr);
}
// function we want to pass to GSL
double a_squared(double a) { return a*a; }
// macro to define an inline lambda wrapping f(double) in GSL signature
#define convert(f) [](double x, void*) { return f(x); }
int main()
{
cout << some_gsl_function(convert(a_squared)) << endl;
}
Personally, as much as I dislike using macros, I would prefer this over my other suggestion. In particular, it solves the problems #Walter pointed out with that idea.
Previous answers - including the accepted one - seem correct, but they are not general enough in case you need to convert other types of function to gsl_function (including member functions for example). So, let me add a more powerful alternative.
If you use the wrapper described here, then you can convert any C++ lambdas to gsl_functions in two simple lines
// Example
gsl_function_pp Fp([&](double x){return a_squared(x);});
gsl_function *F = static_cast<gsl_function*>(&Fp);
This solves any related conversion problems. You can also use std::bind and any std::functions.

vector of function pointers

I'm trying to code a Gameboy emulator and i would like to use a vector of function pointers to call the right function instead of doing a long switch statement.
For example if the program counter point to 0x00 (in memory), the first element of the vector is NOP so void NOP() is called;
but i can't figure how to call the functions.
Z80.h
#include <vector>
using namespace std;
class Z80;
typedef void (Z80::*function_t)();
class Z80
{
public:
vector<function_t> fmap;
...
...
};
Z80.cpp
Z80::Z80()
{
fmap = { &Z80::NOP, &Z80::LDBCnn, &Z80::LDBCmA};
}
void Z80::emulateCycle() {
opcode = memory.readByte(r.pc);
fmap[opcode](); <---ERROR
r.pc++;
}
void Z80::NOP() {
}
this is the error:
IntelliSense: expression preceding parentheses of apparent call must have (pointer-to-) function type
This expression:
fmap[opcode]
gives you a pointer to a member function. You can't just call that - it needs the class instance too. But you're actually calling it from a class method itself - so this is the instance you're looking for:
(this->*fmap[opcode])();
Note that if you want to avoid that bit of syntax and you're using C++11, you can change your fmap to instead be a vector of std::function<void()> and initialize it thusly:
fmap = { std::bind(&Z80::NOP, this), // or [this](){ this->NOP(); }
std::bind(&Z80::LDBCnn, this), // etc.
std::bind(&Z80::LDBCmA, this)};
That will let you actually do:
fmap[opcode]();
I'm not entirely sure that using function pointer in this case is particularly much better than for example a big switch statement.
However, the reason you can't call your member function is that you are not passing your object to the function.
You need this;
(this->*fmap[opcode])();
Another option is to use static/free function pointers, like this:
void (*function_t)(Z80& self);
and call it with:
fmap[opcode](this).
[Or use std::function and std::bind, which covers over the rather (intentionally, apparently) ugly syntax]