Как определить несколько функций одновременно, которые отличаются только по имени (без использования макросов)? - PullRequest
1 голос
/ 20 марта 2019

У меня есть простой математический векторный класс, который в основном просто оборачивает массив 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 Ответ

3 голосов
/ 20 марта 2019

Вам нужно будет использовать макрос для ввода имени, но вы можете сократить срок его действия

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)

Обратите внимание, что вы можете столкнуться с проблемами переопределения этих символов в ::,так что лучше обернуть это в пространство имен.

Посмотри вживую!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...