Serialize C++ functor

2019-01-28 11:55发布

问题:

Can you save the function body of a C++ lambda/functor?

For example, say you have

light0->lightFunction = []( real tEl, real pAz ) -> Vector {

  return Vector(
    // red is up lobe
    std::max<real>( 0., 5*cos(tEl)-4 ),

    // green lower lobe
    std::max<real>( 0., -4*sin(tEl-PI)*cos(pAz-2.5)-3),

    0. ) ;
} ;

And you want to save the function body, so you can load it later (instead of always having to hard code it).

Can you do it?

回答1:

This lambda doesn't have state (not a closure), so it's an ordinary function.

Saving it therefore is the same problem as saving any function. It's not possible in general, but as long as you're loading it back into the exact same process, it may be possible in practice, just by reinterpret_cast-ing the function pointer to a char* and reading a sufficient number of bytes. This will be highly non-portable, though, and may not work at all on some architectures or with some compilers.

Again: There is no standard-compliant way to treat code as data.

On the other hand, there are symbolic expression libraries that allow capture of an expression tree using ordinary code syntax, but then you're not dealing with a functor at all (there is no code, only data).



回答2:

To add to Ben's answer, I'm now doing this:

vector< function <Vector ( real tEl, real pAz )> > funcs ;
funcs.resize( 5 ) ;
// write functions here
funcs[ 0 ] = []( real tEl, real pAz ) -> Vector {
  return Vector(
    // red is up lobe
    std::max<real>( 0., 5*cos(tEl)-4 ),

    // green lower lobe
    std::max<real>( 0., -4*sin(tEl-PI)*cos(pAz-2.5)-3),

    0. ) ;

funcs[ 1 ] = ...

Then when saving, I only save an integer, and at load, point the integer to the correct function in the source code file.