2013-05-12 5 views
15

Zacząłem uczyć się C++ i czytałem książkę, która pisze, że muszę użyć pliku nagłówkowego <string>, ponieważ typ łańcucha nie jest wbudowany bezpośrednio w kompilator. Jeśli korzystam z <iostream>, mogę użyć typu ciągu.Czy muszę używać #include <string> obok <iostream>?

Czy muszę dołączyć nagłówek <string>, gdy chcę użyć typu ciągu, jeśli zawarłem nagłówek <iostream>? Czemu? Czy jest jakaś różnica?

Odpowiedz

17

Tak, musisz uwzględnić to, czego używasz. Nie jest powiedziane, że standardowe nagłówki zawierają się nawzajem (z kilkoma wyjątkami IIRC). Może teraz działać, ale może zawieść na innym kompilatorze.

W twoim przypadku widocznie <iostream> zawiera <string>, bezpośrednio lub pośrednio, ale nie polegaj na nim.

+0

Prawdopodobnie jest to forwardowa deklaracja ciągu znaków ( zawiera , która obejmuje implementację gcc). Myślę, że to standardowe zachowanie (musiałby jednak sprawdzić standard), więc wierzę, że może na nim polegać, gdy nie potrzebuje pełnego typu. – Aleph

+0

@AnotherTest "Mogę użyć typu ciąg" - mówi mi, że potrzebuje pełnego typu. Jeśli tego nie zrobi, to zgodziłaby się taka deklaracja. –

+0

27.5.1 stwierdza, że ​​ musi zawierać . To wymaga tylko 'char_traits', więc nie jestem pewien, czy kompilator musi również przekazywać dalej deklarację' string'. Wciąż wątpię, że jakakolwiek implementacja iostream zawiera cały nagłówek łańcucha. – Aleph

7

Czy muszę zawierać nagłówek <string> gdy chcę użyć typu ciąg, jeśli zawarte w nagłówku <iostream>?

Tak, musisz. Nie można polegać na odpowiednich nagłówkach (np. <string>) będąc pośrednio przez inne nagłówki (np. <iostream>), chociaż może tak być w przypadku niektórych implementacji.

I nawet wtedy, gdy może to wydają do pracy, może to prowadzić do kłopotów, jeśli nie wszystkie z odpowiednimi przeciążenia niektórych operatorów są importowane, czy klasa jest do przodu zadeklarowana w nagłówku ty #include, ale informacje na temat ta klasa pochodząca z innej klasy jest zawarta tylko w nagłówku, który nie dostaje #include d.

Zobacz na przykład this Q&A on StackOverflow jako przykład takich sytuacji.

+0

[ios_base :: getloc] (http://en.cppreference.com/w/cpp/io/ios_base/getloc) zwraca 'std :: locale' według wartości i [locale :: name] (http://en.cppreference.com/w/cpp/locale/locale/name) zwraca 'std :: string' przez wartość, więc' #include 'jest faktycznie wymagane do pełnego zdefiniowania' std :: string'. Tylko osoby niebędące członkami z '' są opcjonalne. – Cubbi

+0

bardzo dobry punkt. Właśnie natknąłem się na problem polegający na tym, że korzystamy z jakiegoś kodu bibliotecznego, którego używamy, i kiedy uaktualniliśmy system z bardzo starego OS/kompilatora do nowszej wersji, kompilacja zepsuła się dla "bez widocznego powodu" poza tym. – user320781