Ogólnie to opisałeś to i szkic masz ogólny. Instynktownie czuję że bez pełnej znajomości problemu, wyjdzie z tego potwór... No ale jak chcesz, możesz np. robić tak:
#include <iostream>
#include <tuple>
#include <variant> // lub experimental/variant jeśli kompilator nieco starszy...
#include <vector>
#include <array>
// Definicje jakiś kontenerów
using VecInt = std::vector<int>;
using ArrInt = std::array<int, 5>;
using ArrVecInt2D = std::array<std::vector<int>, 5>;
using ArrArrInt2D = std::array<ArrInt, 5>;
using VecArrVecInt3D = std::vector<ArrVecInt2D>;
using ArrArrArrInt3D = std::array<ArrArrInt2D, 5>;
// Możliwe konfiguracje jednostkowe...
using Config1 = std::tuple<ArrVecInt2D, VecInt>;
using Config2 = std::tuple<ArrArrInt2D, ArrInt>;
using Config3 = std::tuple<VecArrVecInt3D, ArrVecInt2D>;
using Config4 = std::tuple<ArrArrArrInt3D, ArrArrInt2D>;
// Możliwe konbinacje konfiguracji...
using CombineConfig1 = std::tuple<Config1, Config3>;
using CombineConfig2 = std::tuple<Config2, Config4>;
// Kontener konfiguracji...
using ConfigType = std::variant<CombineConfig1, CombineConfig2>;
int main() {
// Jakieś przykładowe dane by mieć co wyświetlać...
VecInt vec{1, 2, 3, 4};
ArrInt arr{{1, 2, 3, 4, 5}};
ArrVecInt2D arrVecInt2D{ { { 0, 0, 3}, { 1, 3, 5 }, { 0, 0, 3}, { 1, 3, 5 }, { 1, 3, 5 } } };
ArrArrInt2D arrArrInt2D{ { { 1, 3, 4, 5, 6}, { 3, 5, 3, 3, 4}, arr, arr, arr } };
VecArrVecInt3D vecArrVecInt3D{ arrVecInt2D, arrVecInt2D };
ArrArrArrInt3D arrArrArrInt3D{ {arrArrInt2D, arrArrInt2D, arrArrInt2D, arrArrInt2D, arrArrInt2D}};
std::vector<ConfigType> configs{
std::make_tuple( // CombineConfig1
std::make_tuple(arrVecInt2D, vec),
std::make_tuple(vecArrVecInt3D, arrVecInt2D)
),
std::make_tuple( // CombineConfig2
std::make_tuple(arrArrInt2D, arr),
std::make_tuple(arrArrArrInt3D, arrArrInt2D)
)
};
std::size_t confIndex;
std::cout << "Podaj wybór konfiguracji [0, 1]: ";
std::cin >> confIndex; // TODO: Kontrola poprawności
ConfigType& choicedConfig = configs[confIndex];
std::cout << "Wybrano konfigurację: " << choicedConfig.index() << '\n';
// Tu w zależności od .index(), implementacje konfiguracji.
// Zrobił bym szablonem z wymuszeniem instancjonowania kombinacji dla typów szablonu.
// Pobranie danych z std::tuple, zwykłym std::get<X>
}
Dalej już proste implementacje. Początek jest przerażający :)