Reputation: 6012
I have a simple math vector class that basically just wraps a double
array.
Now I want to be able to element-wise apply standard math functions on this vector. E.g. my sqrt()
implementation looks like this:
MyVector sqrt(MyVector x) // side note: makes a copy of the input vector
{
for (double& d : x)
d = std::sqrt(d);
return x;
}
This works fine. The issue I'm facing is, that I want my vector to be usable with basically all functions in <cmath>
that have this signature: double (*)(double)
.
Note that the implementation of these functions would be identical to the one of sqrt()
. The only difference is the function name.
My current solution is a macro:
#define DEFINE(function) \
MyVector function(MyVector x) \
{ \
for (double& d : x) \
d = std::function(d); \
return x; \
}
DEFINE(sqrt)
DEFINE(exp)
DEFINE(sin)
DEFINE(cos)
.
.
.
Is there any non-macro way?
I want these to be free functions to allow generic template code without having to care if the type is a vector or built in.
Upvotes: 1
Views: 79
Reputation: 63152
You will have to use a macro to introduce a name, but you can cut down on how long it is
constexpr auto make_op(double(*op)(double))
{
return [op](MyVector x)
{
std::transform(std::begin(x), std::end(x), std::begin(x), op);
return x;
};
}
#define DEFINE(op) constexpr auto op = make_op(std::op);
DEFINE(sqrt)
DEFINE(exp)
DEFINE(sin)
DEFINE(cos)
Note that you may run into issues of redefining those symbols in ::
, so it's best to wrap this in a namespace.
Upvotes: 3