Z różnych porównań szablonów C ++ i generycznych C # / Java takich jak ten -
Mam wrażenie, że szablony C ++ są implementowane przez pewnego rodzaju przetwarzanie wstępne (zamiana zwykłego tekstu przed parsowaniem), a nie kompilowanie. Ponieważ sprawdzanie typu w szablonach C ++ przypomina makra C. Mam na myśli, że jeśli są jakieś błędy, są to błędy wygenerowanego kodu po przetworzeniu bloków szablonów, a nie samych szablonów. Innymi słowy, są one tylko rodzajem wyższej wersji makr w C.
Potem znalazłem kilka innych faktów na poparcie tego-
Pomyślałem, że jeśli szablony C ++ są implementowane przez przetwarzanie wstępne, pojawią się problemy z dynamicznym łączeniem (przy użyciu .dll). Wspierało to szybkie google.
Inną kwestią jest to, że stałe liczb całkowitych mogą być przekazywane jako argumenty do szablonów. I obsługuje nawet pewnego rodzaju rekurencję. Ale ta rekurencja nie występuje w skompilowanym kodzie zestawu / maszyny. Elementem rekurencyjnym zarządza się w czasie kompilacji, generując funkcje dla każdego wywołania rekurencyjnego, a tym samym posiadając większy, ale szybszy plik wykonywalny.
Chociaż w przeciwieństwie do makr C, ma pewne lepsze umiejętności. Ale czy szablon C ++ nie jest implementowany z jakimś rodzajem przetwarzania wstępnego? Jak to jest zaimplementowane w różnych kompilatorach C ++?
Odpowiedzi:
Szablony C ++ są rodzajem głupich makr Lisp (lub nawet więcej, Scheme). Jest to kompletny język Turinga, który ocenia się w czasie kompilacji, ale jest poważnie ograniczony, ponieważ nie ma dostępu z tego języka do bazowego środowiska C ++. Tak, tak, szablony C ++ można postrzegać jako formę przetwarzania wstępnego, z bardzo ograniczoną interakcją z generowanym kodem.
źródło
Prawdopodobnie największą różnicą jest to, że makra C są rozwijane w fazie wstępnego przetwarzania, zanim zostanie wykonana inna kompilacja, podczas gdy szablony C ++ są częścią kompilacji. Oznacza to, że szablony C ++ są między innymi świadome typu i mają zasięg, a nie są prostym zastępowaniem tekstu. Mogą kompilować się do rzeczywistych funkcji, dzięki czemu unikają większości problemów, które mają makra. Bycie świadomym typu oznacza, że mogą być ogólne lub specjalistyczne: na przykład łatwo jest udostępnić funkcję
swap
szablonu, a także łatwo napisać specjalizacje, które działają dobrze, nawet jeśli obiekty zarządzają pamięcią sterty.Dlatego: szablony C ++ nie przetwarzają wstępnie w tym samym sensie, co makra, nie są rodzajem makra C i nie można używać makr C do powielania tego, co robią szablony.
Szablony znajdują się w plikach nagłówków, a nie w bibliotekach połączonych, to prawda, ale jeśli dostarczasz plik dll, prawdopodobnie dostarczasz również plik nagłówkowy do użycia.
źródło
export
już zaimplementowane. Wiem, że to działa w przypadku funkcji, ale wątpię, aby działało w przypadku klas: skąd znasz ich rozmiar?Czy to ważne, w jaki sposób są wdrażane? Wczesne kompilatory C ++ były tylko procesorami wstępnymi, które dostarczały kod do kompilatora ac, nie oznacza to, że C ++ jest tylko uwielbionym makrem.
Szablony eliminują potrzebę makr, zapewniając bezpieczniejszy, wydajniejszy i specjalizowany (nawet nie sądzę, że to prawdziwe słowo) sposób implementacji kodu dla wielu typów.
Istnieje wiele sposobów wykonywania kodu typu szablonowego w c, z których żaden nie jest zbyt przyjemny, gdy wyjdziesz poza proste typy.
źródło
Istnieją pewne różnice; na przykład szablonów można użyć do utworzenia przeciążenia funkcji, gdy jest to potrzebne, natomiast w przypadku makr trzeba by było rozwinąć makro raz dla każdego możliwego przeciążenia, aby było widoczne dla kompilatora, aby uzyskać dużo nieużywanego kodu.
Kolejną różnicą jest to, że szablony honorują przestrzenie nazw.
źródło
Szablony IMHO, C ++ i makra C miały rozwiązać dwa całkowicie różne problemy. Oryginalna standardowa biblioteka szablonów C ++ była mechanizmem czystego oddzielania klas kontenerów (tablic, list połączonych itp.) Od powszechnie stosowanych funkcji ogólnych (takich jak sortowanie i konkatenacja). Posiadanie abstrakcyjnych reprezentacji wydajnych algorytmów i struktur danych prowadzi do bardziej ekspresyjnego kodu, ponieważ znacznie mniej zgaduje, w jaki sposób najlepiej wdrożyć funkcję działającą na danym fragmencie danych. Makra C były znacznie bardziej zgodne z tym, co zwykle można zobaczyć w makrach Lisp, ponieważ zapewniały środki do „rozszerzenia” języka za pomocą wbudowanego kodu. Fajne jest to, że Standardowa biblioteka C ++ rozszerzyła funkcjonalność szablonów, aby pokryć ogromną większość tego, do czego używamy #define w C.
źródło