我有一个简单的数学 vector 类,基本上只包装了double数组。

现在,我希望能够在此 vector 上逐元素应用标准数学函数。例如。我的sqrt()实现如下所示:

MyVector sqrt(MyVector x) // side note: makes a copy of the input vector
{
    for (double& d : x)
        d = std::sqrt(d);
    return x;
}

这很好。我面临的问题是,我希望我的 vector 基本上可以在<cmath>中具有以下签名的所有函数使用:double (*)(double)

注意,这些功能的实现与sqrt()的实现相同。唯一的区别是函数名称。

我当前的解决方案是一个宏:
#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)
.
.
.

有没有非宏观的方法?

更新资料

我希望这些都是自由函数,以允许通用模板代码,而不必关心类型是 vector 还是内置的。

最佳答案

您将必须使用宏来引入名称,但是您可以减少名称的持续时间

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)

请注意,您可能会遇到在::中重新定义这些符号的问题,因此最好将其包装在 namespace 中。

See it live!

10-08 07:34
查看更多