Jaki problem to rozwiązuje,
Zobacz odpowiedź Dietmar za i odpowiedź remyabel użytkownika .
i czy to zmienia sposób działania standardowych kontenerów?
Nie, nie domyślnie.
Nowe przeciążenia szablonów funkcji składowych find
itp. Pozwalają na użycie typu, który jest porównywalny z kluczem kontenera, zamiast używania samego typu klucza. Aby zapoznać się z uzasadnieniem i szczegółową, starannie napisaną propozycją dodania tej funkcji, zobacz N3465 autorstwa Joaquína Mª Lópeza Muñoza.
Na spotkaniu w Bristolu LWG zgodziło się, że funkcja wyszukiwania heterogenicznego jest użyteczna i pożądana, ale nie mogliśmy być pewni, że propozycja Joaquína będzie bezpieczna we wszystkich przypadkach. Propozycja N3465 spowodowałaby poważne problemy w przypadku niektórych programów (patrz sekcja Wpływ na istniejący kod ). Joaquín przygotował zaktualizowaną wersję roboczą propozycji z kilkoma alternatywnymi wdrożeniami z różnymi kompromisami, co było bardzo przydatne, pomagając LWG zrozumieć zalety i wady, ale wszyscy ryzykowali zerwanie niektórych programów w jakiś sposób, więc nie było zgody co do dodania tej funkcji. Zdecydowaliśmy, że chociaż bezwarunkowe dodawanie tej funkcji nie byłoby bezpieczne, byłoby bezpieczne, gdyby była domyślnie wyłączona i tylko „włączono”.
Kluczową różnicą w propozycji N3657 (która była ostatnią poprawką przeze mnie i STL opartą na N3465 i późniejszą niepublikowaną wersją roboczą Joaquína) było dodanie is_transparent
typu jako protokołu, którego można użyć do włączenia nowej funkcjonalności.
Jeśli nie używasz „przezroczystego funktora” (tj. Takiego, który definiuje is_transparent
typ), wtedy kontenery zachowują się tak samo, jak zawsze i nadal jest to ustawienie domyślne.
Jeśli zdecydujesz się na użycie std::less<>
(co jest nowością w C ++ 14) lub innego typu „przezroczystego funktora”, otrzymasz nową funkcjonalność.
Korzystanie std::less<>
z szablonów aliasów jest łatwe:
template<typename T, typename Cmp = std::less<>, typename Alloc = std::allocator<T>>
using set = std::set<T, Cmp, Alloc>;
Nazwa is_transparent
pochodzi od języka STL N3421, który dodał „operatory diamentowe” do C ++ 14. „Przezroczysty funktor” to taki, który akceptuje dowolne typy argumentów (które nie muszą być takie same) i po prostu przekazuje te argumenty do innego operatora. Taki funktor jest dokładnie tym, czego potrzebujesz do wyszukiwania heterogenicznego w kontenerach asocjacyjnych, więc typ is_transparent
został dodany do wszystkich operatorów rombu i użyty jako typ tagu, aby wskazać, że nowa funkcja powinna być włączona w kontenerach asocjacyjnych. Z technicznego punktu widzenia kontenery nie potrzebują „przezroczystego funktora”, tylko taki, który obsługuje wywoływanie go z typami heterogenicznymi (np. pointer_comp
Typ w https://stackoverflow.com/a/18940595/981959 nie jest przezroczysty zgodnie z definicją STL,pointer_comp::is_transparent
pozwala na użycie go do rozwiązania problemu). Jeśli tylko kiedykolwiek odnośnika w twojej std::set<T, C>
z klawiszami typu T
i int
następnie C
musi być wpłacone z argumentami typu tylko T
i int
(w dowolnej kolejności), to nie musi być naprawdę przejrzyste. Użyliśmy tej nazwy częściowo dlatego, że nie mogliśmy wymyślić lepszej nazwy (wolałbym, is_polymorphic
ponieważ takie funktory używają statycznego polimorfizmu, ale istnieje już std::is_polymorphic
cecha typu, która odnosi się do dynamicznego polimorfizmu).