Создание map c указателями на функции, содержащие разные прототипы С++

Реализую калькулятор с первоначальным приведением в обратную польскую запись и дальнейшим расчётом. В классе пытаюсь создать таблицу операторов, функций с приоритетами, и указателями на функции. Пытаюсь сделать это следующим образом:

//1 функция в строке, 2 приоритет, 3 кол.арг, 4 указатель
QMap<QChar, QPair<int, QPair<int, function(double(double, double))>>> table {
  {'(', {0, 0, nulptr}},
  {'+', {1, 2, add}} и т.д
};

Вопрос в следующем: как организовать структуру table, чтобы можно было хранить функции с разным числом аргументов(3-й параметр - число аргументов функции)

Ранее на Cи делал 2 массива функций, соотносил с последовательностью функций в строке, что в итоге приводило к усложнению добавления функций в калькулятор, т.к. приходилось править в нескольких местах.

typedef double (*F_1ARG)(double);
typedef double (*F_2ARG)(double, double);

#define INC_F_1ARG \
  F_1ARG f_1arg[] = {c_usub, cos, sin, tan, acos, asin, atan, sqrt, log, log10}

#define INC_F_2ARG F_2ARG f_2arg[] = {c_add, c_sub, c_mul, c_div, fmod, pow}

double calculation(Deque *rpn, double x) {
  INC_F_1ARG;
  INC_F_2ARG;
  int op;
  double result, t_1, t_2;
  const char *n_f_2arg = "+-*/A^";
  const char *n_f_1arg = "CDEFGHIJKL";
  Deque *stack = init_deque();
  lexeme_t *t_l = rpn->head;
  while (t_l) {
    if (l_get_type_f(t_l) == VARIABLE) {
      d_push_f(stack, NUMBER, x);
    } else if (l_get_number_f(t_l, &t_1)) {
      d_push_f(stack, NUMBER, t_1);
    } else if (l_get_operation_f(t_l, &op)) {
      if (strchr(n_f_2arg, op)) {
        if (d_get_number_f(stack, &t_2)) free(d_pop_lexem_f(stack));
        if (d_get_number_f(stack, &t_1)) free(d_pop_lexem_f(stack));
        result = f_2arg[strchr(n_f_2arg, op) - n_f_2arg](t_1, t_2);
        d_push_f(stack, NUMBER, result);
      } else if (strchr(n_f_1arg, op)) {
        if (d_get_number_f(stack, &t_1)) free(d_pop_lexem_f(stack));
        result = f_1arg[strchr(n_f_1arg, op) - n_f_1arg](t_1);
        d_push_f(stack, NUMBER, result);
      }
    }
    t_l = t_l->next;
  }
  d_get_number_f(stack, &result);
  d_free(stack);
  free(stack);
  return result;
}

RPN:

void convert_to_rpn(Deque *rpn, const char *infix) {
  int op = 0;
  char *p_str = (char *)infix;
  Deque *stack = init_deque();
  while (*p_str != '\n' && *p_str != '\0') {
    if (*p_str == 'x') {
      d_push_b(rpn, VARIABLE);
      p_str++;
    } else if (isdigit(*p_str)) {
      d_push_b(rpn, NUMBER, strtod(p_str, &p_str));
    } else if (is_function(*p_str)) {
      d_push_f(stack, OPERATION, *p_str++);
    } else if (is_operation(*p_str)) {
      while (d_get_operation_f(stack, &op) && is_less_eq_p(*p_str, op))
        d_push_lexem_b(rpn, d_pop_lexem_f(stack));
      d_push_f(stack, OPERATION, *p_str++);
    } else if (*p_str == '(') {
      d_push_f(stack, OPERATION, *p_str++);
    } else if (*p_str++ == ')') {
      while (d_get_operation_f(stack, &op) && op != '(')
        d_push_lexem_b(rpn, d_pop_lexem_f(stack));
      free(d_pop_lexem_f(stack));
      if (d_get_operation_f(stack, &op) && is_function(op))
        d_push_lexem_b(rpn, d_pop_lexem_f(stack));
    }
  }
  while (stack->head) d_push_lexem_b(rpn, d_pop_lexem_f(stack));
  d_free(stack);
  free(stack);
}

int get_priority(int op) {
  int result = 6;
  const char *s_op = "(+-*/A^BC";
  const int p_op[9] = {0, 1, 1, 2, 2, 2, 3, 4, 4};
  if (strchr(s_op, op)) result = p_op[strchr(s_op, op) - s_op];
  return result;
}

Нашёл на просторах stackoverflow следующую реализацию в стиле Си:

int foo(int a, int b)
{
  return a + b;
}

int bar(double x, double y, double z)
{
  return x * y * z;
}

int main()
{
  int (*f[])() = { foo, bar };
  int a = f[0](2, 3);
  int b = f[1](1., 2., 3.);
}

Хотелось бы реализовать подобное в стиле С++

Реализовал следующим образом, но есть проблема с операторами без функций nullptr

  enum class e_farg_t { DEFAULT, F_1ARG, F_2ARG };
  enum class e_priority_t {DEFAULT, L_PR, M_PR, H_PR, UNARY, FUNC};

  QMap<QChar, QPair<e_priority_t, QPair<e_farg_t, std::variant<std::function<double(double, double)>, std::function<double(double)>>>>> m_fun_ptr {
      // {'(', {e_priority_t::DEFAULT, {e_farg_t::DEFAULT, nullptr}}},
      {'+', {e_priority_t::L_PR, {e_farg_t::F_2ARG, [](double lhs, double rhs) -> double {return lhs + rhs;}}}},
      {'-', {e_priority_t::L_PR, {e_farg_t::F_2ARG, [](double lhs, double rhs) -> double {return lhs - rhs;}}}},
      {'*', {e_priority_t::M_PR, {e_farg_t::F_2ARG, [](double lhs, double rhs) -> double {return lhs * rhs;}}}},
      {'/', {e_priority_t::M_PR, {e_farg_t::F_2ARG, [](double lhs, double rhs) -> double {return lhs / rhs;}}}},
      {'A', {e_priority_t::M_PR, {e_farg_t::F_2ARG, (double(*)(double, double))&std::fmod}}},
      {'^', {e_priority_t::H_PR, {e_farg_t::F_2ARG, (double(*)(double, double))&std::pow}}},
      // {'B', {e_priority_t::UNARY, {e_farg_t::DEFAULT, nullptr}}},
      {'C', {e_priority_t::UNARY, {e_farg_t::F_1ARG, [](double a) -> double {return -a;}}}},
      {'D', {e_priority_t::FUNC, {e_farg_t::F_1ARG, (double(*)(double))&std::cos}}},
      {'E', {e_priority_t::FUNC, {e_farg_t::F_1ARG, (double(*)(double))&std::sin}}},
      {'F', {e_priority_t::FUNC, {e_farg_t::F_1ARG, (double(*)(double))&std::tan}}},
      {'G', {e_priority_t::FUNC, {e_farg_t::F_1ARG, (double(*)(double))&std::acos}}},
      {'H', {e_priority_t::FUNC, {e_farg_t::F_1ARG, (double(*)(double))&std::asin}}},
      {'I', {e_priority_t::FUNC, {e_farg_t::F_1ARG, (double(*)(double))&std::atan}}},
      {'J', {e_priority_t::FUNC, {e_farg_t::F_1ARG, (double(*)(double))&std::sqrt}}},
      {'K', {e_priority_t::FUNC, {e_farg_t::F_1ARG, (double(*)(double))&std::log}}},
      {'L', {e_priority_t::FUNC, {e_farg_t::F_1ARG, (double(*)(double))&std::log10}}}
      };

Ответы (0 шт):