Używam deklaracji „using” w C ++, aby dodać std :: string i std :: vector do lokalnej przestrzeni nazw (aby zaoszczędzić wpisywanie niepotrzebnych „std ::”).
using std::string;
using std::vector;
class Foo { /*...*/ };
Jaki jest zakres tej deklaracji? Jeśli zrobię to w nagłówku, czy wstrzyknie te deklaracje „using” do każdego pliku cpp, który zawiera nagłówek?
using
deklaracji (lubusing
dyrektywy) w zakresie pliku w dołączonym pliku / nagłówku! To spowoduje ból głowy u użytkowników nagłówka.using
deklarację (a fortiori dyrektywa ) w nagłówku w ogóle , nawet w obrębie przestrzeni nazw! Zobacz zakres używania deklaracji w przestrzeni nazw dla problemów, które powoduje.using
w zakresie klas i funkcji jest bezpieczne w omawianym problemie.Odpowiedzi:
Kiedy # dołączasz plik nagłówkowy w C ++, umieszcza on całą zawartość pliku nagłówkowego w miejscu, w którym umieściłeś go w pliku źródłowym. Zatem dołączenie pliku, który ma
using
deklarację, ma dokładnie taki sam efekt, jak umieszczenieusing
deklaracji na początku każdego pliku, który zawiera ten plik nagłówkowy.źródło
using
deklarację wewnątrz anamespace
, jest ona ograniczona do zakresu tej przestrzeni nazw, więc ogólnie jest OK (ze zwykłymi zastrzeżeniami dotyczącymi twoich konkretnych potrzeb i stylu).Nie ma nic specjalnego w plikach nagłówkowych, które powstrzymywałyby
using
deklarację przed ujawnieniem. Jest to proste podstawianie tekstu przed rozpoczęciem kompilacji.Możesz ograniczyć
using
deklarację do zakresu:źródło
using
wewnątrz funkcji (lub nawetTEST
makra gtest !) Sprawia, że moje życie jest o wiele lepsze!Zakres instrukcji using zależy od tego, gdzie się ona znajduje w kodzie:
źródło
using
instrukcji w zakresie klasy ...? Miałem to samo pytanie, co OP, ponieważ chciałem uniknąć pisania wstd::
każdym miejscu. Mam klasy, które używają wielu wektorów z inteligentnymi wskaźnikami, a pięcioznakowystd::
prefiks dodaje dużo długości linii - co wydaje mi się gorsze. Więc zastanawiałem się, czyusing
dyrektywa w przestrzeni nazw zawierającej klasę jest w porządku? (Nawet jeśli w nagłówku.)namespace { ... }
?Zakres jest dowolnym zakresem, w którym znajduje się deklaracja using.
Jeśli jest to zasięg globalny, będzie to zasięg globalny. Jeśli jest w zasięgu globalnym pliku nagłówkowego, będzie w zasięgu globalnym każdego pliku źródłowego, który zawiera nagłówek.
Dlatego ogólną radą jest unikanie używania deklaracji w globalnym zakresie plików nagłówkowych .
źródło
W przytoczonym przypadku plik („jednostka tłumaczeniowa”), co oznacza tak, każdy plik, który go zawiera.
Możesz również umieścić instrukcję using wewnątrz klasy, w takim przypadku obowiązuje ona tylko dla tej klasy.
Ogólnie rzecz biorąc, jeśli musisz określić przestrzeń nazw w nagłówku, często najlepiej jest po prostu w pełni zakwalifikować każdy wymagany identyfikator.
źródło
using
deklaracja w klasie nie zachowuje się tak samo, jak poza klasą - np. Nie możesz jej użyć bringcout
zamiaststd::cout
do zakresu klasy.To jest poprawne. Zakres to moduł używający
using
deklaracji. Jeśli jakiekolwiek pliki nagłówkowe, które zawiera moduł, mająusing
deklaracje, zakresem tych deklaracji będzie ten moduł, a także wszelkie inne moduły, które zawierają te same nagłówki.źródło
Jest kilka komentarzy, które są raczej bez zastrzeżeń, kiedy mówią „Nie”. To zbyt surowe, ale musisz zrozumieć, kiedy jest OK.
Pisanie
using std::string
nigdy nie jest w porządku. Pisanieusing ImplementationDetail::Foo
we własnym nagłówku, gdy ten nagłówek deklaruje ImplementationDetail :: Foo może być OK, więcej, jeśli deklaracja using ma miejsce w Twojej przestrzeni nazw. Na przykładźródło
MyNS::Foo
using boost::posix_time::ptime
. Jasne, że użytkownik mógłby pisać,MyNS::ptime
ale to nie koniec świata i może to być zrekompensowane wygodą posiadania funkcji takich jakMyFunction(ptime a, ptime b)
.using std::string
nigdy nie jest w porządku? Nawet we własnej przestrzeni nazw, aby zapisać wielestd::
prefiksów?