Suppose I am trying to use a function which accepts a binary function and calls it with some arguments:
typedef double (*BinaryFunction)(double a, double b);
typedef double (*UnaryFunction)(double a);
// Can't change this
double ExternalFunction(BinaryFunction binaryFunction)
{
return binaryFunction(1, 2);
}
Now suppose a user of my code is going to provide me with a unary function. My goal is to convert it into a binary function so that I can call ExternalFunction with it:
double MyFunction(UnaryFunction unaryFunction)
{
BinaryFunction binaryFunction = /* want a function (a, b) -> unaryFunction(a + b) */;
return ExternalFunction(binaryFunction);
}
How do I do this? Just to be clear, I understand that this would be easy if the unary function were known at compile time, but it's not - it will be an argument to my function. Thanks in advance.
Here's a summary of my attempts. I believe I understand why these don't work, but I'm providing them so you can see what I've been thinking so far.
I can't use a lambda, because I'd have to capture UnaryFunction, and capturing lambdas can't be converted to function pointers:
double MyFunction(UnaryFunction unaryFunction)
{
BinaryFunction binaryFunction = [unaryFunction](double a, double b){ return unaryFunction(a + b); };
return ExternalFunction(binaryFunction);
}
Use std::function ? Can't get that to work either:
void MyFunction(UnaryFunction unaryFunction)
{
std::function<double(double, double)> binaryFunctionTemp = [unaryFunction](double a, double b)
{
return unaryFunction(a + b);
};
BinaryFunction binaryFunction = binaryFunctionTemp.target<double(double, double)>();
ExternalFunction(binaryFunction);
}
What about a function object? Won't work because we'd need a pointer to a member function:
class BinaryFromUnary
{
public:
BinaryFromUnary(UnaryFunction unaryFunction) : unary_(unaryFunction) {};
double operator()(double a, double b)
{
return unary_(a + b);
}
private:
UnaryFunction unary_;
};
void MyFunction(UnaryFunction unaryFunction)
{
BinaryFromUnary functionObject(unaryFunction);
std::function<double(double, double)> binaryFunction = functionObject;
ExternalFunction(binaryFunction.target<double(double, double)>());
}
Even had a go with std::bind (and probably messed it up):
struct Converter {
Converter(UnaryFunction unary) : unary_(unary) {}
double binary(double a, double b) const { return unary_(a + b); }
UnaryFunction unary_;
};
void MyFunction(UnaryFunction unaryFunction)
{
Converter converter(unaryFunction);
std::function<double(double, double)> binaryFunction = std::bind( &Converter::binary, converter, _1, _2);
ExternalFunction(binaryFunction.target<double(double, double)>());
}
Tried a couple of other things along the same lines. Any ideas would be much appreciated.