Dlaczego kompilator nie pozwala mi na przekazywanie deklaracji typedef?
Zakładając, że to niemożliwe, jaka jest najlepsza praktyka utrzymywania małego drzewa integracji?
c++
typedef
forward-declaration
użytkownik96825
źródło
źródło
typedef
nazwa złożonego typu szablonu wielopoziomowego przy użyciu deklaracji przekazywania w ten sposób jest dość złożona i trudna. Nie wspominając, że może to wymagać zanurzenia się w szczegóły implementacji ukryte w domyślnych argumentach szablonu. A rozwiązaniem końcowym jest długi i nieczytelny kod (szczególnie gdy typy pochodzą z różnych przestrzeni nazw) bardzo podatny na zmiany w oryginalnym typie.Dla tych z was jak ja, którzy chcą przekazać deklarację struktury w stylu C, która została zdefiniowana przy użyciu typedef, w jakimś kodzie c ++ znalazłem rozwiązanie, które wygląda następująco ...
źródło
Aby „fwd zadeklarować typedef”, musisz fwd zadeklarować klasę lub strukturę, a następnie możesz wpisać typ zadeklarowany. Kompilator akceptuje wiele identycznych typów czcionek.
długa forma:
skrócona forma:
źródło
W C ++ (ale nie w zwykłym C) jest całkowicie legalne dwukrotne wpisanie typu, o ile obie definicje są całkowicie identyczne:
źródło
A
pola w ten sposób, skoroA
z definicji jest puste?Ponieważ aby zadeklarować typ, jego rozmiar musi być znany. Możesz przekazać deklarację wskaźnika do typu lub wpisać do wskaźnika typ.
Jeśli naprawdę tego chcesz, możesz użyć idiomu pimpl, aby zmniejszyć liczbę włączeń. Ale jeśli chcesz użyć typu zamiast wskaźnika, kompilator musi znać jego rozmiar.
Edycja: j_random_hacker dodaje ważną kwalifikację do tej odpowiedzi, w zasadzie, że rozmiar musi być znany, aby użyć tego typu, ale deklaracja przekazania może być złożona, jeśli musimy tylko wiedzieć, że typ istnieje , aby utworzyć wskaźniki lub odniesienia do rodzaj. Ponieważ OP nie wyświetlał kodu, ale narzekał, że się nie skompiluje, założyłem (prawdopodobnie poprawnie), że OP próbował użyć tego typu, a nie tylko się do niego odwoływać.
źródło
Korzystanie z deklaracji przesyłania zamiast pełnych
#include
jest możliwe tylko wtedy, gdy nie zamierzasz używać samego typu (w zakresie tego pliku), ale wskaźnik lub odwołanie do niego.Aby użyć samego typu, kompilator musi znać jego rozmiar - stąd należy zobaczyć jego pełną deklarację - dlatego
#include
potrzebna jest pełna .Jednak rozmiar wskaźnika lub odwołania jest znany kompilatorowi, niezależnie od wielkości pointee, więc wystarczająca jest deklaracja forward - deklaruje nazwę identyfikatora typu.
Co ciekawe, gdy używasz wskaźnika lub odwołania do
class
lubstruct
typów, kompilator może obsługiwać typy niekompletne, co pozwala zaoszczędzić czas na przekazywanie deklarowanych typów pointee:źródło
Miałem ten sam problem, nie chciałem zadzierać z wieloma typedefami w różnych plikach, więc rozwiązałem to z dziedziczeniem:
był:
zrobił:
Działa jak urok. Oczywiście musiałem zmienić wszelkie odniesienia
po prostu
źródło
Zastąpiłem
typedef
(using
a konkretnie) dziedziczeniem i konstruktorem (?).Oryginalny
Zastąpiony
W ten sposób mogłem przekazać deklarację za
CallStack
pomocą:źródło
Jak zauważył Bill Kotsias, jedynym rozsądnym sposobem na zachowanie poufności danych typedef twojego punktu i przesłanie ich dalej jest dziedziczenie. Możesz to zrobić nieco lepiej z C ++ 11. Rozważ to:
źródło
Podobnie jak @BillKotsias, użyłem dziedziczenia i zadziałało to dla mnie.
Zmieniłem ten bałagan (który wymagał wszystkich nagłówków boost w mojej deklaracji * .h)
do tej deklaracji (* .h)
a implementacja (* .cpp) była
źródło