I am adding the new module in some large library. All methods here are implemented as static. Let me briefly describe the simplified model:
typedef std::vector<double> TData;
double test ( const TData &arg ) { return arg ( 0 ) * sin ( arg ( 1 ) + ...;}
double ( * p_test ) ( const TData> &arg) = &test;
class A
{
public:
static T f1 (TData &input) {
.... //some computations
B::f2 (p_test);
}
};
Inside f1() some computations are performed and a static method B::f2 is called. The f2 method is implemented by another author and represents some simulation algorithm (example here is simplified).
class B
{
public:
static double f2 (double ( * p_test ) ( const TData &arg ) )
{
//difficult algorithm working p_test many times
double res = p_test(arg);
}
};
The f2 method has a pointer to some weight function (here p_test). But in my case some additional parameters computed in f1 for test() methods are required
double test ( const TData &arg, const TData &arg2, char *arg3.... ) { }
How to inject these parameters into test() (and so to f2) to avoid changing the source code of the f2 methods (that is not trivial), redesign of the library and without dirty hacks 🙂 ?
The most simple step is to override f2
static double f2 (double ( * p_test ) ( const TData &arg ), const TData &arg2, char *arg3.... )
But what to do later? Consider, that methods are static, so there will be problems with objects.
Updated question
Is it possible to make a pointer to a function dependent on some template parameter or do something like that
if (condition) res = p_test(arg);
else res = p_test2(arg, arg2, arg3);
Not gonna happen. If you can’t modify the source of a function taking a function pointer, you’ll have to use an exception vomit to gain the extra arguments. If you had a C++11 compiler (that does not exist yet) which supports
thread_local, it’s theoretically possible to do something better, or you could use OS-specific TLS. But as of right now, the only portable solution is an exception vomit.Alternatively, in your scenario, modifying
f2doesn’t seem to be impossible, only difficult. However, the difficulty of altering it to take astd::function<double(const TData&)>would be very low- all you’d have to do is change the argument type, thanks to operator overloading. It should be a very simple change for even a complex function, as you’re only changing the type of the function parameter, all the call sites will still work, etc. Then you can pass a proper function object made throughbindor a lambda or somesuch.