W standardowej bibliotece C ++ są funkcje do konwersji z ciągów znaków na typy numeryczne:
stoi
stol
stoll
stoul
stoull
stof
stod
stold
ale uważam, że nużące jest używanie ich w kodzie szablonu. Dlaczego nie ma funkcji szablonów, takich jak:
template<typename T>
T sto(...)
konwertować ciągi znaków na typy numeryczne?
Nie widzę żadnego technicznego powodu, aby ich nie mieć, ale może coś mi brakuje. Mogą specjalizować się w wywoływaniu bazowych nazwanych funkcji i używaniu enable_if
/ concepts
do wyłączania typów nienumerycznych.
Czy w standardowej bibliotece są jakieś przyjazne szablony alternatywne do konwertowania napisów na typy numeryczne i na odwrót w efektywny sposób?
c++
string-conversion
Mircea Ispas
źródło
źródło
Odpowiedzi:
C ++ 17 ma taką ogólną funkcję ciągu na liczbę, ale ma inną nazwę. Oni poszli z
std::from_chars
, który jest przeciążony dla wszystkich typów numerycznych.Jak widać, pierwsze przeciążenie przyjmuje dowolny typ liczb całkowitych jako parametr wyjściowy i przypisze mu wartość, jeśli to możliwe.
Można go użyć w następujący sposób:
Jak widać, może działać w ogólnym kontekście.
źródło
To nie jest szablon i nie działa z ustawieniami narodowymi, ale jeśli nie jest to ogranicznik programu, C ++ 17 ma już to, czego chcesz:
std::from_chars
Występują przeciążenia dla wszystkich typów liczb całkowitych i zmiennoprzecinkowych, a interfejs jest taki sam, z wyjątkiem ostatnich parametrów, które są różne dla typów całkowitych i zmiennoprzecinkowych (ale jeśli wartość domyślna jest w porządku, nie trzeba zmienić cokolwiek). Ponieważ nie jest to funkcja rozpoznająca ustawienia regionalne, jest również dość szybka. Uderzy w inną funkcję konwersji łańcucha na wartość i generalnie jest o rząd wielkości.
Jest bardzo dobry film CPPCON o
<charconv>
(nagłówekfrom_chars
mieszka) Stephana T. Lavaveja, który można obejrzeć na temat jego użycia i wydajności tutaj: https://www.youtube.com/watch?v=4P_kbF0EbZMźródło
stoi
i jego przyjaciele (konwersje wspomniane w pytaniu) również nie działają z ustawieniami regionalnymi, więc nie jest to showstopper.Nie zyskałbyś wiele, ponieważ w takim wyrażeniu jak
Nie ma (łatwego) sposobu, aby wydedukować pożądany typ parametru szablonu. Musisz pisać
co w pewnym stopniu przeczy celowi zapewnienia funkcji ogólnej. Z drugiej strony, a
przyda ci się, jak sobie uświadomiłeś. W C ++ 17 jest to
std::from_chars
, co robi mniej więcej dokładnie to (nie jest to szablon, ale zestaw przeciążeń i wymaga wskaźników do znaków zamiast łańcucha, ale to tylko drobne szczegóły).PS Nie ma łatwego sposobu, aby wydedukować pożądany typ w powyższym wyrażeniu, ale istnieje sposób. Nie sądzę, aby rdzeń twojego pytania był dokładnie podpisem, o który prosiłeś, i nie sądzę, że poniższy sposób jest dobrym sposobem na jego wdrożenie, ale wiedziałem, że istnieje sposób na
int x = sto("1");
skompilowanie powyższego i byłem ciekawy to zobaczyć w akcji.Działa to zgodnie z przeznaczeniem, ale ma poważne wady, być może co najważniejsze pozwala na pisanie
auto x = sto(s);
, tzn. Jest łatwe w użyciu.źródło
auto x = sto(s)
? Ta konkretna implementacja psuje się, ponieważconverter::x
jest to odwołanie, które wykracza poza zakres, ale można to naprawić. Wystarczy usunąć odniesienie i polegać nastd::string
semantyce przenoszenia.converter
, nie jestem również pewien, czy użycie operatora konwersji szablonu było najlepszym wyborem, co można naprawić. Może nie jest tak źle, jak początkowo myślałemNależy używać rozwiązania kompatybilnego ze wszystkimi (nawet starszymi kompilatorami C ++, takimi jak C ++ - 98) boost :: lexical_cast, który jest szablonem do konwersji między typem liczbowym a ciągiem znaków na dwa sposoby.
Przykład:
Zobacz: https://www.boost.org/doc/libs/1_42_0/libs/conversion/lexical_cast.htm
źródło
W starszych wersjach C ++ stringstream jest twoim przyjacielem. Jeśli dobrze rozumiem, poniższe informacje mogą być dla Ciebie interesujące. Jest to C ++ 11.
https://wandbox.org/permlink/nUNiUwWWTr7a0NXM
Ta metoda działa w C ++ 11 i jest dość ogólna. Z mojego doświadczenia wynika, że ta metoda jest solidna, ale nie najbardziej wydajna.
źródło