#STL

wszystkie notatki oznaczone etykietą "STL"

Niespójne i mylące konstruktory w std::string

Kiedyś często problemem były niejawne konwersje między typami w C++, które szczególnie uwidaczniały się przy konstruktorach konwersji… Kto by pomyślał, że dziś nadał trywialne błędy można popełnić przez jakieś zaszłości historyczne, usilne zachowanie kompatybilności i brak spójności w definiowaniu konstruktorów, nawet tych w Standardzie ;) Problemy te co jakiś czas są na nowo “odkrywane”, ostatnio powróciły w nieco prześmiewczym kodzie na twitterze: const std::string str = "Modern C++"; std::string s1 { "Modern C++", 3 }; std::string s2 { str, 3 }; std::cout << "S1: " << s1 << "\n"; std::cout << "S2: " << s2 << "\n"; Intuicyjnie mogłoby się wydawać, że obiekty s1 i s2 będą zawierać taką samą zawartość.

Czytaj dalej

C++20 formalnie (prawie) gotowe...

http://herbsutter.com/2020/02/15/trip-report-winter-iso-c-standards-meeting-prague/ http://www.reddit.com/r/cpp/comments/f47x4o/202002_prague_iso_c_committee_trip_report_c20_is/

C++17 formalnie (prawie) gotowe...

W marcu tego roku, na spotkaniu komitetu standaryzacyjnego C++ w Kona, technicznie zakończono prace nad nową odsłoną standardu języka C++. Nowy draft DIS (N4660) przesłano do finalnego balotowania przez ISO (ISO ballot) i za 5-6 miesięcy oficjalnie powitamy C++17. Zapewne, prócz drobnych ewentualnych korekt w dokumencie, technicznie nic się nie zmieni, więc nieformalnie takie drafty traktowane są już przez społeczność jako standard. Obecnie ostatnim dostępnym dokumentem jest N4659 (różniący się jedynie formatowaniem od niedostępnego publicznie N4660).

Czytaj dalej

MPU: klasy cech kontenerów STL

Kolejna notatka z serii MPU, opisująca kilka ciekawych konstrukcji zawartych w mistycznym MetaPrograming-Unit. Tym razem o klasach cech opisujących typy kontenerów zawartych w STL. Każdy programista C++ zaznajomiony jest z klasami cech (traits) i ich wielkim potencjałem. Dla tych wszystkich, którzy nie do końca łapią temat, dwa zdania wprowadzające. Klasy cech w C++ są specyficznym typem klas szablonów dostarczających w czasie kompilacji informacji o innych typach bądź strukturach danych. Wykorzystywane są głownie w programowaniu generycznym, przez inne obiekty lub algorytmy do określenia polityki działania lub szczegółów implementacji i realizacji.

Czytaj dalej

Algorytm set_differences

Zbiór gotowych algorytmów ze standardowej biblioteki języka C++ jest bardzo użyteczny, o tym nie trzeba długo nikogo przekonywać. Choć czasem, gdy trzeba wykonać kilka rzeczy naraz, bądź kilka kolejnych algorytmów na tych samych danych, możemy stracić na wydajności, szczególnie jak danych jest wiele, a złożoność algorytmu liniowa. Czasem warto trochę pomyśleć i napisać coś dedykowanego, ewentualnie połączyć 2 algorytmy. Oczywiście tylko, jeśli jest to możliwe i w miarę proste, np. gdy oba algorytmy mają podobną budowę.

Czytaj dalej

Algorytmy STL na tablicach

Często w programach napisanych w C do pobierania rozmiaru tablic (ilości elementów) alokowanych przez kompilator na stosie stosuje się prostą konstrukcję z operatorem sizeof. ładnie “opakowaną” w makro do łatwego użycia: #define SizeOfArray(array) sizeof(array) / sizeof(array[0]) W C++ zamiast makra lepiej wykorzystać wzorzec, a wtedy można to przedstawić w takiej postaci: template<typename T, size_t N> inline size_t SizeOfArray(const T (&)[N]) { return N; } Wersja cpplusowa jest bezpieczniejsza. Próba wywołania SizeOfArray() na wskaźniku zakończy się błędem w czasie kompilacji, w przeciwieństwie do makra, które dopiero da znać o tym problemie w run-time.

Czytaj dalej

Algorytm copy_if

Nic nie jest doskonałe. Tak samo C++ i STL ma swoje braki i różne przeoczenia. W standardowej bibliotece języka C++ zabrakło bardzo użytecznego algorytmu, jakim jest copy_if, czyli kopiowania z predykatem. Prawdopodobnie został on usunięty przez przypadek z dostarczanych przez bibliotekę algorytmów generycznych. Na szczęście z tego co się orientuję, można znaleźć o nim wzmianki w drafcie nowego standardu (C++0x), także jest szansa, że błąd ten zostanie naprawiony. Tymczasem, jeśli jest potrzeba, to można korzystać z bardzo prostej implementacji tego algorytmu:

Czytaj dalej

Iteratory strumienia w C++

Pisałem o numeric_limits jako zapomnianej części biblioteki numerycznej, dziś do tego “worka” mogę dorzucić iteratory strumieni jako rzadko używane “twory”. Niektórych może zdziwić ten fakt, że strumienie także posiadają iteratory, a ich wykorzystanie może bardzo nam pomoc i uprościć kod. Na początek najlepiej zapoznać się z tym co mówi dokumentacja na temat istream_iterator i ostream_iterator z nagłówka iterator. Często iteratory te są wykorzystywane w różnych przykładach innych algorytmów do szybkiego pobierania danych z strumienia wejściowego i wyświetlania na wyjściowym, w produkcyjnym oprogramowaniu rzadko je można spotkać.

Czytaj dalej

Wzorzec numeric_limits

Standardowa biblioteka języka C++ zawiera wiele ciekawych i przydatnych narzędzi w codziennej pracy developera C++, a po wejściu w życie C++0x będzie jeszcze ciekawiej. Czasem nawet nie mamy świadomości lub zapominamy o ciekawych perełkach jakie można tam znaleźć. Jednym z zapomnianych i chyba rzadko używanych komponentów biblioteki STL jest szablon numeric_limits będący “odłamkiem” numerycznej części biblioteki. Wzorzec ten wraz z specjalizacjami dla typów wbudowanych zdefiniowany jest w pliku nagłówkowym limits. Jego przeznaczeniem jest dostarczenie informacji o cechach typów numerycznych.

Czytaj dalej

Konwersja wskaźnika do iteratora

Czym jest iterator w STL każdy wiedzieć powinien. Mogę wspomnieć ze jest to typ z zachowaniem podobnym do wskaźnika, który służy do poruszania się po kontenerach biblioteki standardowej, ale nie jest to wskaźnik, mimo iż w większości implementacjach jest to opakowany w obiekt wskaźnik. Kilka flejmów na ten temat można znaleźć w usenetowych archiwach pl.comp.lang.c ;) Konwersja (słowo tutaj zbytnio nie pasuje) iteratora wskazującego na dany element kontenera do typowego wskaźnika jest bardzo prosta.

Czytaj dalej