如何一次定义几个仅因名称而不同的功能(不使用宏)?

时间:2019-03-20 16:00:50

标签: c++ c++17

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

现在,我希望能够在此向量上逐元素应用标准数学函数。例如。我的sqrt()实现看起来像这样:

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

这很好。我面临的问题是,我希望向量可以在<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)
.
.
.

有没有非宏观的方式?

更新

我希望它们是自由函数,以允许通用模板代码,而不必关心类型是向量还是内置的。

1 个答案:

答案 0 :(得分:3)

您将不得不使用宏来引入名称,但是您可以减少名称的长度

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)

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

See it live!