Как правильно инициализировать статическую карту? Нужна ли нам статическая функция, которая ее инициализирует?
449
Использование C ++ 11:
#include <map>
using namespace std;
map<int, char> m = {{1, 'a'}, {3, 'b'}, {5, 'c'}, {7, 'd'}};
Использование Boost.Assign :
#include <map>
#include "boost/assign.hpp"
using namespace std;
using namespace boost::assign;
map<int, char> m = map_list_of (1, 'a') (3, 'b') (5, 'c') (7, 'd');
Лучший способ - использовать функцию:
источник
extern
переменные не будут иметь своих правильных значений в этом «перед главным конструктором времени выполнения», если компилятор только виделextern
объявление, но еще не столкнулся с фактическим определением переменной .const map<int,int> m = create_map()
(и, таким образом, инициализировать константные члены класса в списке инициализации:struct MyClass {const map<int, int> m; MyClass(); }; MyClass::MyClass() : m(create_map())
Это не сложная задача сделать что-то похожее на повышение. Вот класс с тремя функциями, включая конструктор, для воспроизведения того, что сделал Boost (почти).
Применение:
Приведенный выше код работает лучше всего для инициализации глобальных переменных или статических членов класса, который необходимо инициализировать, и вы не знаете, когда он будет использован первым, но вы хотите убедиться, что значения доступны в нем.
Если, скажем, вам нужно вставить элементы в существующий std :: map ... вот еще один класс для вас.
Применение:
Смотрите его в действии с GCC 4.7.2 здесь: http://ideone.com/3uYJiH
############### ВСЕ НИЖЕ ЭТО ОБОЗРЕНИЕ #################
РЕДАКТИРОВАТЬ :
map_add_values
Класс ниже, который был оригинальным решением, которое я предложил, потерпит неудачу, когда дело доходит до GCC 4.5+. Пожалуйста, посмотрите на код выше, как добавить значения в существующую карту.Применение:
ПРИМЕЧАНИЕ: ранее я использовал
operator []
для добавления фактических значений. Это невозможно, как прокомментировал Далле.##################### ОКОНЧАТЕЛЬНЫЙ РАЗДЕЛ #####################
источник
operator[]
принимает только один аргумент.error: conflicting declaration ‘map_add_values<int, int> my_map’
error: ‘my_map’ has a previous declaration as ‘std::map<int, int> my_map’
Вот еще один способ, который использует 2-элементный конструктор данных. Никаких функций не требуется для его инициализации. Здесь нет стороннего кода (Boost), нет статических функций или объектов, нет хитростей, просто C ++:
Поскольку я написал этот ответ, C ++ 11 отсутствует. Теперь вы можете напрямую инициализировать контейнеры STL, используя новую функцию списка инициализаторов:
источник
Например:
Если map является членом данных класса, вы можете инициализировать его непосредственно в заголовке следующим образом (начиная с C ++ 17):
источник
Я бы обернул карту внутри статического объекта и поместил код инициализации карты в конструктор этого объекта, чтобы вы были уверены, что карта создана до выполнения кода инициализации.
источник
Просто хотел поделиться чистой работой C ++ 98 вокруг:
источник
Ты можешь попробовать:
источник
{1, 2}
вместоstd::pair<int, int>(1, 2)
.Это похоже
PierreBdR
, без копирования карты.источник
Если вы застряли с C ++ 98 и не хотите использовать boost, здесь есть решение, которое я использую, когда мне нужно инициализировать статическую карту:
источник
У вас есть несколько очень хороших ответов здесь, но я для меня, это похоже на случай "когда все, что вы знаете, это молоток" ...
Самый простой ответ на вопрос, почему не существует стандартного способа инициализации статической карты, - нет веской причины когда-либо использовать статическую карту ...
Карта - это структура, предназначенная для быстрого поиска неизвестного набора элементов. Если вы знаете элементы заранее, просто используйте C-массив. Введите значения отсортированным образом или выполните сортировку по ним, если вы не можете этого сделать. Затем вы можете получить производительность log (n), используя stl :: functions для зацикливания записей, lower_bound / upper_bound. Когда я проверял это ранее, они обычно работают как минимум в 4 раза быстрее, чем карта.
Преимущества многократно ... - более высокая производительность (* 4, я измерял на многих типах процессоров, всегда около 4) - более простая отладка. Просто проще увидеть, что происходит с линейным макетом. - Тривиальные реализации операций копирования, если это станет необходимым. - Он не выделяет память во время выполнения, поэтому никогда не выдаст исключение. - Это стандартный интерфейс, поэтому его очень легко обменивать, библиотеки DLL или языки и т. Д.
Я мог бы продолжить, но если вы хотите больше, почему бы не взглянуть на многочисленные блоги Страуструпа на эту тему.
источник
map
также является полезной формой для представления частичной функции (функция в математическом смысле; но также, в некотором смысле, в смысле программирования). Массив не делает этого. Вы не можете, скажем, искать данные из массива, используя строку.