Мне нужен только словарь или ассоциативный массив string
=> int
.
Для этого случая существует карта типов C ++.
Но мне нужна только одна карта для всех экземпляров (-> static), и эту карту нельзя изменить (-> const);
Я нашел этот способ с помощью библиотеки boost
std::map<int, char> example =
boost::assign::map_list_of(1, 'a') (2, 'b') (3, 'c');
Есть ли другое решение без этой библиотеки? Я пробовал что-то подобное, но всегда возникают проблемы с инициализацией карты.
class myClass{
private:
static map<int,int> create_map()
{
map<int,int> m;
m[1] = 2;
m[3] = 4;
m[5] = 6;
return m;
}
static map<int,int> myMap = create_map();
};
v = k + 'a' - 1
.Ответы:
источник
Boost.Assign
подобный дизайн тоже довольно красиво :)cout << A::myMap[1];
вmain()
. Выдает ошибку. Ошибка не возникает, если я удаляюconst
квалификаторы, поэтому я полагаю, что map неoperator[]
может обрабатывать aconst map
, по крайней мере, не в реализации g ++ библиотеки C ++.const_map.cpp:22:23: error: passing ‘const std::map<int, int>’ as ‘this’ argument of ‘std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](const key_type&) [with _Key = int; _Tp = int; _Compare = std::less<int>; _Alloc = std::allocator<std::pair<const int, int> >; std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type = int; std::map<_Key, _Tp, _Compare, _Alloc>::key_type = int]’ discards qualifiers [-fpermissive]
Стандарт C ++ 11 представил унифицированную инициализацию, которая делает это намного проще, если ваш компилятор поддерживает ее:
См. Также этот раздел из Professional C ++ о unordered_maps.
источник
Я это сделал! :)
Прекрасно работает без C ++ 11
источник
Если вы сочтете
boost::assign::map_list_of
полезным, но по какой-то причине не можете его использовать, вы можете написать свой собственный :Полезно знать, как такие вещи работают, особенно когда они такие короткие, но в этом случае я бы использовал функцию:
a.hpp
a.cpp
источник
Другой подход к проблеме:
Это более эффективно, поскольку нет однотипного копирования из стека в кучу (включая конструктор, деструкторы для всех элементов). Важно это или нет, зависит от вашего варианта использования. Со струнами все равно! (но вы можете найти эту версию «чище», а можете и не найти)
источник
Если карта должна содержать только записи, которые известны во время компиляции, а ключи карты являются целыми числами, то вам вообще не нужно использовать карту.
источник
switch
ужасно, хотя. А почему бы и нетreturn key + 'a' - 1
?return key + 'a' - 1
это не сработает для его реального отображения.Вы можете попробовать это:
MyClass.h
MyClass.cpp
С этой реализацией постоянная статическая карта ваших классов является закрытым членом и может быть доступна другим классам с помощью общедоступного метода get. В противном случае, поскольку он постоянен и не может быть изменен, вы можете удалить общедоступный метод get и переместить переменную карты в публичный раздел классов. Однако я бы оставил метод createMap закрытым или защищенным, если требуется наследование и / или полиморфизм. Вот несколько примеров использования.
Я отредактировал свой исходный пост, в исходном коде, который я опубликовал, не было ничего плохого, он был скомпилирован, построен и запущен правильно, просто моя первая версия, которую я представил в качестве ответа, была объявлена как общедоступная, а карта была const, но не статический.
источник
Если вы используете компилятор, который по-прежнему не поддерживает универсальную инициализацию, или у вас есть резервирование использования Boost, другой возможной альтернативой будет следующая
источник
Вызов функции не может появляться в постоянном выражении.
попробуйте это: (просто пример)
источник
static map<int,int> myMap = create_map();
неверный.struct testdata { testdata(int){} }; struct test { static const testdata td = 5; }; testdata test::td;
он не будет скомпилирован, даже если инициализация выполняется с постоянным выражением (5
). То есть «постоянное выражение» не имеет отношения к правильности (или ее отсутствию) исходного кода.Я часто использую этот паттерн и рекомендую вам тоже его использовать:
Конечно, это не очень удобно для чтения, но без других библиотек это лучшее, что мы можем сделать. Также не будет никаких лишних операций, таких как копирование с одной карты на другую, как в вашей попытке.
Это даже более полезно внутри функций: Вместо:
Используйте следующее:
Мало того, что вам больше не нужно здесь иметь дело с логической переменной, у вас не будет скрытой глобальной переменной, которая проверяется, если инициализатор статической переменной внутри функции уже был вызван.
источник