С++: есть ли способ объединить списки различных типов переменных в один?

Вот искомая функция, написанная на Котлине:

    // these 3 classes inherit from MenuItem class
    val subOptions: MutableList<MenuOption> = mutableListOf(),
    val entries: List<MenuEntry> = emptyList(),
    val actions: List<MenuAction> = emptyList() 

    fun getOrderedMenuItems(): List<MenuItem> = entries.plus(actions).plus(subOptions)

Есть ли способ обойти эту проблему с помощью std::list или другого типа контейнера? Если нет, то как еще это можно перевести? Любые подсказки будут высоко оценены.

@изменить

Возможно, я не ясно выразился. По сути, я хотел соединить эти списки в один список. Я пытался использовать splice() и merge() как таковые:

list<MenuItem> mergedList = list<MenuItem>();
mergedList.splice(mergedList.end(), actions);

И я получил это:

ни один экземпляр перегруженной функции std::__cxx11::list‹_Tp, _Alloc›::splice [с _Tp=MenuItem, _Alloc=std::allocator] не соответствует списку аргументов -- типы аргументов: (std::_List_iterator, std ::__cxx11::list‹MenuAction, std::allocator›) -- тип объекта: std::__cxx11::list‹MenuItem, std::allocator›

Вот что помогло мне:

list<MenuItem> MenuOption::getOrderedMenuItems() {
    list<MenuItem> mergedList = list<MenuItem>();
    for(MenuItem const& i : actions) {
        mergedList.push_back(i);
    }
    for(MenuItem const& i : subOptions) {
        mergedList.push_back(i);
    }
    for(MenuItem const& i : entries) {
        mergedList.push_back(i);
    }
    return mergedList;
}

person Larry Fishermann    schedule 24.08.2020    source источник
comment
Вы искали в документации? std::merge   -  person thibsc    schedule 24.08.2020
comment
Запрашивать прямой перевод кода, как правило, не разрешается. Пожалуйста, покажите попытку, которую вы предприняли при написании этого на С++.   -  person cigien    schedule 24.08.2020
comment
Пожалуйста, прочитайте, stackoverflow.com/questions/58280538/ У меня возникает соблазн идентифицировать его как дубликат, потому что я подозреваю, что вы учитывая.   -  person Yunnosch    schedule 24.08.2020
comment
@Yunnosch Пожалуйста, не предлагайте это :) В сообщении нет никаких доказательств того, что ОП вообще знает какой-либо С++, и они действительно могут попробовать это, даже если в этом нет необходимости.   -  person cigien    schedule 24.08.2020
comment
Возможно, вы могли бы использовать std::any и std::merge   -  person Ranoiaetep    schedule 24.08.2020
comment
@thibsc std::merge предназначен для объединения двух отсортированных диапазонов   -  person Ayxan Haqverdili    schedule 24.08.2020
comment
@cigien Хм. Я хочу сказать, что использование пустых указателей требует БОЛЬШЕ знаний о том, на что на самом деле указывает, как объясняют ответы. Ваш комментарий как будто указывает на то, что вы читали там что-то еще, но я не могу представить, как вы это сделали.   -  person Yunnosch    schedule 24.08.2020
comment
@Yunnosch Ну, я думал об этом с точки зрения ОП. Они нажимают на ссылку, видят void*, не полностью понимают ответ и, немного погуглив, обнаруживают, что могут использовать void* для решения своей проблемы, и тратят время на написание плохого кода: p Просто хотел, чтобы ОП избежал этого: )   -  person cigien    schedule 24.08.2020
comment
Прочтите это нарезку объектов   -  person n. 1.8e9-where's-my-share m.    schedule 25.08.2020
comment
@cigien Вздрогнул. у вас, кажется, еще более пессимистическое мнение, чем у меня, о новых пользователях StackOverflow, когда наступит сентябрь. И я не вижу ошибки в вашем мышлении. Вздох.   -  person Yunnosch    schedule 25.08.2020


Ответы (1)


Вам нужно использовать векторы (или списки, но это худший вариант) указателей (умных или нет; умные указатели предпочтительнее, но я не показываю их для краткости).

std::vector<MenuItem*> out;
// these 3 classes inherit from MenuItem class
std::vector<MenuOption*> subOptions;
std::vector<MenuEntry*> entries;
std::vector<MenuAction*> actions;

out.insert(out.end(), entries.begin(), entries.end());
out.insert(out.end(), actions.begin(), actions.end());
out.insert(out.end(), subOptions.begin(), suboptions.end());

Затем вы можете std::sort вектор out, если вам нужен отсортированный вектор. Также можно использовать std::merge, если исходные векторы уже отсортированы. Вам, вероятно, потребуется передать пользовательский компаратор любой функции, иначе они будут сравнивать указатели, что, вероятно, не то, что вам нужно.

См. этот вопрос и ответ для получения дополнительной информации.

person n. 1.8e9-where's-my-share m.    schedule 24.08.2020
comment
Где ОП упомянул, что они работают (или собираются работать) с отсортированными диапазонами? std::merge кажется неуместным для этого вопроса - person Ayxan Haqverdili; 24.08.2020
comment
@Ayxan, исходная функция называется getOrderedMenuItems. Я не знаю, какой порядок имеется в виду, поэтому на всякий случай объясню, как получить отсортированный вывод. - person n. 1.8e9-where's-my-share m.; 24.08.2020