C++ массив функций с разным количеством аргументов

я новичок в программировании, а плюсы только начал учить, сильно не бейте.

Пытаюсь сделать функцию “menu” у которой 2 аргумента:

  1. Массив (функций / указателей на функции)
  2. Массив строк (названия этих функций)

Дошел до такого вида:

std::vector <std::function<void()>> VectorFunctoins = { f1,    f2,    f3    };
std::vector <std::string/*******/> VectorNameString = {"one", "two", "three"};
menu(VectorFunctoins, VectorNameString);

Но, оно работает только если у функций (f1, f2, f3) нет аргументов, или их количество одинаковое.

Если я дам функции аргумент ( f3(N) ), то будут ошибки:

  1. C2440 инициализация: невозможно преобразовать "initializer list" в "std::vector<std::function<void (void)>,std::allocator<std::function<void (void)>>>"

  2. Е0289 отсутствуют экземпляры конструктора "std::vector<_Ty, _Alloc>::vector [с _Ty=std::function<void ()>, _Alloc=std::allocator<std::function<void ()>>]", соответствующие списку аргументов

Я понимаю, что массив должен содержать элементы одного типа, но можно ли сделать так чтобы оно работало с разным количеством аргументов (и разными типами этих аргументов)?

Сам код:

#include<iostream>

void f1()
{
    std::cout << "f1\n";
}

void f2()
{
    std::cout << "f2\n";
//  return 1;
}

void f3(int a)
{
    std::cout << "f3\n";
//  return 1;
}


#include"C:\Users\PC\Desktop\University\Laboratory work\ОС,ООП\menu\menu.h"
int main()
{
    int N = 1;

    std::vector <std::function<void()>> VectorFunctoins = {f1,     f2,    f3(N)};
    std::vector <std::string/*******/> VectorNameString = {"one", "two", "three"};
    menu(VectorFunctoins, VectorNameString);
}

Код файла “menu.h”:

#pragma once

#include<iostream>
#include<string>
#include<vector>
#include<functional>


void menu(std::vector <std::function<void()>> Vector_Functions,
          std::vector <std::string/********/> Vector_Function_Names)
{
    int choose = 0;
    do
    {
        system("cls");  
        std::cout << "Choose: " << "\n";
        std::cout << "0)Exit: " << "\n";
        std::cout               << "\n";

        for (int i = 0; i < Vector_Function_Names.size(); i++)
        {   std::cout << i + 1 << ")" << Vector_Function_Names[i] << "\n";   }

        std::cout << "\n";
        std::cout << "input: ";
        std::cin >> choose;
        system("cls");

        if (choose != 0)
        {   Vector_Functions[choose - 1](); system("pause");   };

    } while (choose != 0);  std::cout << "Bye!..." << "\n";
}

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

Автор решения: Лд Лд

В итоге получилось меню которое принимает на 1й аргумент массив из функций с любым количеством и типом параметров, а на 2й массив названий для этих функций

Программа:

#include<iostream>

void f1()
{
    std::cout << "f1" << "\n";
}

bool f2(int i, float f, char c1, char c2)
{
    std::cout << "f2" << "\n";
    std::cout << "int   i - " << i << "\n";
    std::cout << "float f - " << f << "\n";
    std::cout << "char c1 - " << c1 << "\n";
    std::cout << "char c2 - " << c2 << "\n";
    
    return true;
}


#include"C:\Users\PC\Desktop\University\Laboratory work\ОС,ООП\menu\menu.h"

int main()
{
    int   I = 1;
    float F = 2.2;
    char  C = '1';


    std::vector <std::function<void()>> VectorFunctoins = {f1,    [&I, &F, &C]() {f2(I, F, C, '2'); }};
    std::vector <std::string/*******/> VectorNameString = {"one", "two",                             };
    menu(VectorFunctoins, VectorNameString);
}

меню 1я функция 'f1' 2я функция 'f2'

Само меню:

#pragma once

#include<iostream>
#include<string>
#include<vector>
#include<functional>



void menu(std::vector <std::function<void()>> Vector_Functions,
          std::vector <std::string/********/> Vector_Function_Names)
{
    int choose = 0;
    do
    {
        system("cls");  
        std::cout << "Choose: " << "\n";
        std::cout << "0)Exit: " << "\n";
        std::cout               << "\n";

        for (int i = 0; i < Vector_Function_Names.size(); i++)
        {   std::cout << i + 1 << ")" << Vector_Function_Names[i] << "\n";   }

        std::cout << "\n";
        std::cout << "input: ";
        std::cin >> choose;
        system("cls");

        if (choose != 0)
        {   Vector_Functions[choose - 1](); system("pause");   };

    } while (choose != 0);  std::cout << "Bye!..." << "\n";
}
→ Ссылка
Автор решения: Swift - Friday Pie

Естественно в массив нельзя положить разные типы по определению. Список аргументов функции является частью ее типа.

Но вот если передаваемые функции аргументы можно описать одним типом, тогда у вас получится вариант шаблона "Callback". Сам аргумент функции будет "сообщением" (Message). Message может быть

  1. каким-то базовым классом для всех видов сообщений или
  2. гибким контейнером данных, вроде protobuf, или
  3. индексом в каком-то глобальном хранилище, из которого которому функция может достать данные (кэш запросов\сообщений), что является частной формой реализации protobuf.
→ Ссылка