Potrzebuję tylko słownika lub tablicy asocjacyjnej string
=> int
.
W tym przypadku istnieje mapa typów C ++.
Ale potrzebuję tylko jednej mapy dla wszystkich instancji (-> statyczna) i tej mapy nie można zmienić (-> stała);
Znalazłem ten sposób w bibliotece boost
std::map<int, char> example =
boost::assign::map_list_of(1, 'a') (2, 'b') (3, 'c');
Czy istnieje inne rozwiązanie bez tej biblioteki? Próbowałem czegoś takiego, ale zawsze pojawiają się problemy z inicjalizacją mapy.
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
.Odpowiedzi:
źródło
Boost.Assign
podobnego projektu też jest całkiem fajne :)cout << A::myMap[1];
domain()
. Daje błąd. Błąd nie występuje, jeśli usunęconst
kwalifikatory, więc wydaje mi się , że mapyoperator[]
nie obsługująconst map
, przynajmniej nie, implementacji biblioteki C ++ g ++.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]
W standardzie C ++ 11 wprowadzono jednolitą inicjalizację, co znacznie upraszcza, jeśli Twój kompilator to obsługuje:
Zobacz także tę sekcję z Professional C ++ , na unordered_maps.
źródło
Ja to zrobiłem! :)
Działa dobrze bez C ++ 11
źródło
Jeśli uznasz to za
boost::assign::map_list_of
przydatne, ale z jakiegoś powodu nie możesz go użyć, możesz napisać własne :Warto wiedzieć, jak takie rzeczy działają, zwłaszcza gdy są takie krótkie, ale w tym przypadku użyłbym funkcji:
a.hpp
a.cpp
źródło
Inne podejście do problemu:
Jest to bardziej wydajne, ponieważ nie ma jednego typu kopiowania ze stosu na stertę (w tym konstruktor, destruktory na wszystkich elementach). To, czy ma to znaczenie, czy nie, zależy od twojego przypadku użycia. Nie ma znaczenia w przypadku sznurków! (ale możesz znaleźć tę wersję „czystszą” lub nie)
źródło
Jeśli mapa ma zawierać tylko wpisy, które są znane w czasie kompilacji, a klucze do mapy są liczbami całkowitymi, to w ogóle nie musisz używać mapy.
źródło
switch
jest jednak okropne. Dlaczego niereturn key + 'a' - 1
?return key + 'a' - 1
to nie zadziała w przypadku jego rzeczywistego mapowania.Możesz spróbować tego:
MyClass.h
MyClass.cpp
W tej implementacji stała statyczna mapa klas jest członkiem prywatnym i może być dostępna dla innych klas przy użyciu publicznej metody get. W przeciwnym razie, ponieważ jest stała i nie można jej zmienić, możesz usunąć publiczną metodę get i przenieść zmienną mapy do sekcji public class. Pozostawiłbym jednak metodę createMap jako prywatną lub chronioną, jeśli wymagane jest dziedziczenie i / lub polimorfizm. Oto kilka przykładów użycia.
Zredagowałem mój oryginalny post, nie było nic złego w oryginalnym kodzie, w którym napisałem, skompilowałem, zbudowałem i uruchomiłem poprawnie, po prostu moja pierwsza wersja przedstawiłem jako odpowiedź, że mapa została uznana za publiczną, a mapa została const, ale nie było statyczne.
źródło
Jeśli używasz kompilatora, który nadal nie obsługuje uniwersalnej inicjalizacji lub masz zastrzeżenia co do korzystania z funkcji Boost, inna możliwa alternatywa byłaby następująca
źródło
Wywołanie funkcji nie może pojawić się w wyrażeniu stałym.
spróbuj tego: (tylko przykład)
źródło
static map<int,int> myMap = create_map();
jest nieprawidłowy.struct testdata { testdata(int){} }; struct test { static const testdata td = 5; }; testdata test::td;
kompilacja nie powiedzie się, nawet jeśli inicjalizacja jest wykonywana za pomocą stałego wyrażenia (5
). Oznacza to, że „wyrażenie stałe” nie ma znaczenia dla poprawności (lub jej braku) początkowego kodu.Często używam tego wzoru i polecam go również:
Jasne, że nie jest zbyt czytelny, ale bez innych bibliotek jest to najlepsze, co możemy zrobić. Nie będzie też żadnych zbędnych operacji, takich jak kopiowanie z jednej mapy na drugą, jak w przypadku twojej próby.
Jest to jeszcze bardziej przydatne w funkcjach: Zamiast:
Użyj następujących:
Nie tylko nie musisz już tutaj zajmować się zmienną boolowską, nie będziesz mieć ukrytej zmiennej globalnej, która jest sprawdzana, jeśli inicjator zmiennej statycznej wewnątrz funkcji został już wywołany.
źródło