Prawdopodobnie staram się osiągnąć to, co niemożliwe, ale StackExchange zawsze mnie zaskakuje, więc proszę zrób to:Czy możliwe jest sprawdzanie w czasie kompilacji w trybie ciąg do mapy?
Muszę zamapować nazwę na liczbę całkowitą. Nazwy (około 2k) są unikalne. Nie będzie żadnych dodatków ani usunięć do tej listy, a wartości nie zmienią się w czasie wykonywania.
Implementowanie ich jako zmiennych const int
daje mi możliwość sprawdzania istnienia i typu w czasie kompilacji. Również jest to bardzo jasne i pełne w kodzie. Błędy są łatwo zauważalne.
Implementacja ich jako std::map<std::string, int>
daje mi dużą elastyczność w budowaniu nazw, które można wyszukiwać za pomocą manipulacji ciągami. Mogę użyć tego, aby nadać ciągom znaków parametry dla funkcji, które mogą wysyłać zapytania do listy dla wielu wartości przez dołączanie przedrostków/końcówek do tego ciągu. Mogę również przechodzić przez kilka wartości, tworząc część liczbową nazwy klucza ze zmiennej pętli.
Teraz moje pytanie brzmi: czy istnieje metoda łączenia obu zalet? Brakujące sprawdzanie podczas kompilacji (szczególnie w przypadku istnienia klucza) prawie zabija drugą metodę dla mnie. (Zwłaszcza, gdy std::map
cicho zwraca 0
, jeśli klucz nie istnieje, co powoduje trudności w znalezieniu błędów.) Jednak możliwości dodawania pętli i dodawania przedrostków/sufiksów są tak cholernie przydatne.
Wolałbym rozwiązanie, które nie korzysta z żadnych dodatkowych bibliotek, takich jak boost, ale proszę, zasugeruj je jednak, ponieważ i tak będę mógł je ponownie wdrożyć.
Przykładem na to, co zrobić z mapą:
void init(std::map<std::string, int> &labels)
{
labels.insert(std::make_pair("Bob1" , 45));
labels.insert(std::make_pair("Bob2" , 8758));
labels.insert(std::make_pair("Bob3" , 436));
labels.insert(std::make_pair("Alice_first" , 9224));
labels.insert(std::make_pair("Alice_last" , 3510));
}
int main()
{
std::map<std::string, int> labels;
init(labels);
for (int i=1; i<=3; i++)
{
std::stringstream key;
key << "Bob" << i;
doSomething(labels[key.str()]);
}
checkName("Alice");
}
void checkName(std::string name)
{
std::stringstream key1,key2;
key1 << name << "_first";
key2 << name << "_last";
doFirstToLast(labels[key1.str()], labels[key2.str()]);
}
Kolejnym celem jest to, że kod pokazany na main()
rutynowych pobytów jak łatwe i szczegółowe, jak to możliwe. (Musi być zrozumiany przez nieprogramistów.) Funkcja init()
będzie generowana kodowo przez niektóre narzędzia. Funkcje doSomething(int)
są poprawione, ale mogę pisać wokół nich funkcje opakowania. Programy pomocnicze, takie jak checkName()
, mogą być bardziej skomplikowane, ale muszą być łatwe do debugowania.
brzmi jak chcesz budować ciągi w czasie wykonywania, ale jakoś się to sprawdzane w czasie kompilacji? –
Istnieją sposoby konwertowania wyliczeń na ich odpowiednie ciągi, więc powinno być możliwe. Chociaż trudno jest zobaczyć, jak jest to czas kompilacji, jeśli budujesz łańcuchy w czasie wykonywania, to: –
'std :: map' z pewnością ma zdolność czy wstawiłeś element. Jednym ze sposobów jest "wstaw". – chris