Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

casting std::function to a different std::function and invoking it?

I have a question about casting an std::function of one type to another with the same number of arguments or more and then invoking it since it works on all the compilers but i am not sure if it is a defined behavior.

std::function<void(int, float)> func1 = [](int a, float b){
  std::cout << a << std::endl;
  std::cout << b << std::endl;
};

std::function<void(int, float, int, double)>& func2 =
*reinterpret_cast<std::function<void(int, float, int, double)>*>(&func1);

func2(1, 2.0f, 3, 4.0);

This seems to properly call func1 with the expected args 1, 2.0f. What happens to the other passed arguments. What happens when i swap func1 and func2 and invoke it with 2 arguments when it is expecting 4. Is it a well defined behaviour since it works on msvc, gcc, clang or is it some kind of fluke and i should avoid it. Can anyone with more expertise elaborate on the topic?

like image 853
Nikolai Petrov Ivanov Avatar asked Feb 02 '26 01:02

Nikolai Petrov Ivanov


1 Answers

This seems to properly call func1 [...]

You cannot cast a std::function<Sig1> to a std::function<Sig2>. They are unrelated types, despite being specializations of the same function template. One cannot simply refer to the other. It's undefined behavior. One potential consequence of undefined behavior is that the code does seem to work. And then you change compilers. Or compiler versions. Or just some random unrelated code that causes the optimizer to do different things. Or...

If you want a new function with a new signature, you have to create a new function object. One way, if you want to simply drop the last two arguments, would be:

std::function<void(int, float, int, double)> func2 = [func1](int a, float b, int, double){
    func1(a, b);
};

Another would be to take advantage of the fact that bind simply drops unused arguments:

std::function<void(int, float, int, double)> func2 = std::bind(func1, _1, _2);

Both of these are fine.

like image 159
Barry Avatar answered Feb 03 '26 13:02

Barry



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!