#c #c 11
#c #c 11 #c
Вопрос:
Когда мы используем сложный контейнер в C , например
std::vector<std::map<std::string, std::set<std::string>>> table;
Единственный способ добавить пустую карту (которая может представлять строку или столбец) — это инициализировать новый элемент и вернуть его обратно. Например, с
table.push_back(std::map<std::string, std::set<std::string>>());
Есть ли какой-нибудь способ избежать повторного объявления типа и просто добавить правильный типизированный элемент?
Ответ №1:
Позже я обнаружил, что из clion’s IntelliSense есть один полезный метод emplace_back()
. Это создает новый объект правильного типа и добавляет его в конец вектора.
table.emplace_back();
Ответ №2:
Вы можете воспользоваться copy-list-initialization (начиная с C 11) и просто написать
table.push_back({});
Ответ №3:
До C 11 иногда я использовал x.resize(x.size() 1)
, в C 11 или более поздней версии вы можете использовать x.push_back({})
.
Ответ №4:
Хотя другие ответы верны, я добавлю, что, если вы не смогли воспользоваться этим подходом, вы могли бы извлечь выгоду из объявления некоторых псевдонимов типов, чтобы сократить имя типа контейнера.
Я могу, конечно, только догадываться о логическом значении ваших контейнеров, и это еще одна вещь, которую это исправляет!
using PhilosopherNameType = std::string;
using NeighboursType = std::set<PhilosopherNameType>;
using NeighbourMapType = std::map<PhilosopherNameType, NeighboursType>;
std::vector<NeighbourMapType> table;
table.push_back(NeighbourMapType());
Я упоминаю об этом, потому что вы, вероятно, все еще можете извлечь выгоду из этого в других местах.
Комментарии:
1. согласовано. В тех же строках приведены типы, которые предоставляет вам STL (vector::value_type iirc)
2. Есть ли практическая разница между использованием «using …. = …» и typedef?