Streaming of std::function

Hi!

Since the topic came up indirectly in a recent support forum post ( Cloning vs. Copying TF1 ) I would be interested to know if any of the ROOT-Devs (Axel?) see any chance that it will be possible to store “std::function” Objects in root-files ( especially in the case of c++ lambdas ).

Cheers,
Jochen

Hi Jochen,

storing a lambda is logically equivalent to store a function, i.e. code rather than “data”: at the moment this is a functionality which is not at the top of our priority list. The closest concept ROOT presently offers is TFormula, where we store a string which is then jitted when deserialising the object.
Is this functionality needed in any of your workflows?

Danilo

Hi Danilo,

thx for your quick reply. I’m currently designing/imlpementing a signal driven simulation system for (primarily) connectionist cognitive models. In essence, I have a bunch of entities that can emit signals and receive signals. To receive signals, an entity “registers” a callback function at the simulation system.

The thing is: I would like to have the ability to pause a simulation run at (almost) any point in time, store it to disk, and reload it at some point later and continue the simulation. My current approach just uses a single virtual function as callback which has to be overridden. However, this makes the “client” code in the actual simulation entities rather “ugly” since you have to distinguish in each call of the callback function for which signal the callback was called. It would be much more elegant, if the entities could just register different std::functions for different signals. Yet, I have no idea how i could re-establish these callbacks after I load the simulation from a file.

The closest thing as far as i can see it right now would be to identify the callbacks via TClass/TMethod/MethodCall and use somehow the Execute()-facilities of TMethodCall to invoke the callbacks. However, i fear that this would be an extremly inefficient way to perform the callbacks (I have to admit that I have to still measure this - currently just an educated guess). Would it be possible to somehow extract a std::function from TMethod or TMethodCall?

Cheers,
Jochen

Hi Jochen,

suppose to save your functions as strings in a rootfile, what you can do to call them from within your compiled code is a procedure like the following:

gInterpreter->Declare("double times2(double x){return 2*x;}");
auto times2OutsideTheInterpreter = (double (*)(double)) gInterpreter->ProcessLine("times2");
times2OutsideTheInterpreter(3);

What is happening is a call to a function which has been JIT-ted from within the compiled code. The performance should be optimal (de facto you are calling compiled code with an additional hop).

Cheers,
Danilo

Hi Danilo,

this is a neat trick! I think I can use it already for my purposes, i.e., to allow clients to register either arbitrary class member functions (given they have the right parameters), or lambda functions as a string parameter. From my first measurements the performance hit is acceptable-ish and depends on the amount of work that is actually done in the callback function.

Cheers,
Jochen

Hi Jochen,

great. Let us know if you face serious performance degradations beyond the aforementioned indirection.

Cheers,
Danilo