Лучший способ передать математический оператор через параметры метода - PullRequest
0 голосов
/ 11 февраля 2020

Как показывает вопрос, у меня есть метод следующим образом:

template<typename LN, typename RN, typename LV, typename RV>
VariableValue dataArithmetic(LN leftNode, RN rightNode, LV leftV, RV rightV) {

    if (leftNode.type() == typeid(ChartData*) && rightNode.type() == typeid(ChartData*)) {
        ChartData* temp1 = boost::get<ChartData*>(leftNode);
        ChartData* temp2 = boost::get<ChartData*>(rightNode);
        temp1->data *= temp2->data; // <----------------
        return temp1;
    }
    else if (leftNode.type() == typeid(ChartData*) || rightNode.type() == typeid(ChartData*)) {
        if (leftNode.type() == typeid(ChartData*)) {
            ChartData* temp = boost::get<ChartData*>(leftNode);
            float value = boost::lexical_cast<float>(rightV);
            temp->data *= value; // <----------------
            return (VariableValue)temp;
        }
        else if (rightNode.type() == typeid(ChartData*)) {
            ChartData* temp = boost::get<ChartData*>(rightNode);
            float value = boost::lexical_cast<float>(leftV);
            temp->data *= value; // <----------------
            return (VariableValue)temp;
        }
    }
    return 0;
}

В настоящее время этот метод закодирован для применения умножения, как показано // <---------------- Однако мне нужен этот метод для поддержки всех основных c арифметика c значения + - * /

Учитывая, что эта функция вызывается с помощью:

VariableValue dataArith = dataArithmetic(leftNode, rightNode, leftV, rightV);

Я бы хотел, чтобы метод принял параметр, который указывает, какой математический оператор должен применяться таким образом как:

VariableValue dataArith = dataArithmetic(leftNode, rightNode, leftV, rightV, **MULTIPLICATION**);

Каков наилучший способ сделать это?

Ответы [ 3 ]

1 голос
/ 11 февраля 2020

Шаблон функции для операции:

template<typename LN, typename RN, typename LV, typename RV, typename OP>
VariableValue dataArithmetic(LN leftNode, RN rightNode, LV leftV, RV rightV, OP op) {

А затем передайте соответствующую операцию:

dataArithmetic(..., std::multiplies<>{})
dataArithmetic(..., std::plus<>{})
dataArithmetic(..., std::minus<>{})
dataArithmetic(..., std::divides<>{})

До C ++ 14 для этих объектов функций в стандартной библиотеке требуется шаблон параметры (std::multiplies<double>{}). C ++ 14 или позже, они не делают.

0 голосов
/ 11 февраля 2020

Спасибо Джеффу Гарретту за указатель

Решение:

template<typename LN, typename RN, typename LV, typename RV, typename OP>
VariableValue dataArithmetic(LN leftNode, RN rightNode, LV leftV, RV rightV, OP op) {

    if (leftNode.type() == typeid(ChartData*) && rightNode.type() == typeid(ChartData*)) {
        ChartData* temp1 = boost::get<ChartData*>(leftNode);
        ChartData* temp2 = boost::get<ChartData*>(rightNode);
        //;
        ChartData* temp = new ChartData(op(temp1->data, temp2->data));
        return temp1;
    }
    else if (leftNode.type() == typeid(ChartData*) || rightNode.type() == typeid(ChartData*)) {
        if (leftNode.type() == typeid(ChartData*)) {
            ChartData* temp1 = boost::get<ChartData*>(leftNode);
            float value = boost::lexical_cast<float>(rightV);
            ChartData* temp = new ChartData(op(temp1->data, value));
            return (VariableValue)temp;
        }
        else if (rightNode.type() == typeid(ChartData*)) {
            ChartData* temp1 = boost::get<ChartData*>(rightNode);
            float value = boost::lexical_cast<float>(leftV);
            ChartData* temp = new ChartData(op(temp1->data, value));
            return (VariableValue)temp;
        }
    }
    return 0;
}

Позвонить:

VariableValue dataArith = dataArithmetic(leftNode, rightNode, leftV, rightV, std::multiplies<>{});
0 голосов
/ 11 февраля 2020

Pass std::binary_function или просто std::function.

...