Jak czytam standard Google, nie można using namespace foo;
nigdzie używać dyrektywy. Dyrektywa wprowadza wszystko zadeklarowane w przestrzeni nazw i jest częstą przyczyną kolizji i nieoczekiwanego zachowania. Inni cytowali bardzo powszechny: masz gdzieś własną metodę max lub min, która zderza się z plikiem src, w którym ktoś zawiera nagłówek twojej metody, a następnie mówiusing namespace std;
W niektórych miejscach dozwolone jest posiadanie deklaracji użytkowania, która ma formę using ::foo::bar;
Ludzie lubią umieszczać w swoich kodach dyrektywy, ponieważ oszczędzają dużo pisania, ale wiążą się z ryzykiem. Jeśli masz plik z wieloma instrukcjami cout, rozumiem, że nie chcę pisać std :: cout sto razy, ale możesz po prostu powiedzieć, używając :: std :: cout. Traktuję je jak deklaracje zmienne: zakreśl je tam, gdzie są potrzebne. Jeśli jedna funkcja w pliku 10 musi zapisać dane wyjściowe, nie deklaruj metody cout u góry, umieść ją w tej funkcji, która wykonuje dane wyjściowe.
#include <ostream>
//using namespace std; // NO!
//using ::std::cout; // less bad than using namespace, but I prefer to scope it
int main(int argc, char** argv)
{
int rc = do_some_stuff(argc, argv);
using ::std::endl;
if (rc) { // print the success report
using ::std::cout;
cout << "The test run completed. The return code was " << rc << '.' << endl;
} else {
using ::std::cerr;
cerr << "Unable to complete the test run." << endl;
}
return 0 == rc;
}
To trochę ekstremalne, gdy tylko kilka wierszy generuje dane wyjściowe, ale masz pomysł.
Inną rzeczą, którą można zrobić, jest alias lub typedef, aby zminimalizować pisanie. Nie uważam, aby std :: cokolwiek było tak źle, ale mamy ogromny zestaw źródeł z kilkadziesiąt modułów i czasami musimy pisać kod jak console_gui::command_window::append("text")
. To po pewnym czasie staje się nudne i powoduje wiele długich linii. Jestem za czymś takim
typedef console_gui::command_window cw;
cw::append("text");
tak długo, jak aliasy są wykonywane w zasięgu lokalnym i zachowują wystarczający kontekst, aby kod był czytelny.
std::endl
do jawnego flushowania nastdout
/stderr
jest zwykle dość zbędne, te strumienie są powiązane zstdout
/ istderr
tak. To nawet trochę spowalnia.Jest tak, ponieważ: 1) pokonuje cały cel przestrzeni nazw, którym jest ograniczenie kolizji nazw; 2) udostępnia globalnej przestrzeni nazw całą przestrzeń nazw określoną w dyrektywie using.
Na przykład, jeśli włączysz i zdefiniujesz własną funkcję max (), zderzy się ona ze std :: max ().
http://en.cppreference.com/w/cpp/algorithm/max
Preferowane jest użycie std :: member_you_wish_to_use, ponieważ wyraźnie określa, której przestrzeni nazw użyć.
źródło
std::max()
z prefiksem przestrzeni nazw. Czy się mylę?using
dyrektywami, ponieważ w tym przypadku zepsułoby to funkcję max (), gdybyś ją zdefiniował i włączył <algorytm>. To prosty przypadek, ale nigdy nie wiesz, co możesz złamać. Musisz znać całą bibliotekę, aby mieć pewność, że jej nie złamałeś, ale nie wiesz, czy Twój kod się zepsuje (tj. Kolizja nazw) w przyszłości.Cytując podany przez Ciebie link:
Styl Google zabrania używania importowania przestrzeni nazw w kontekście globalnym, ale pozwala to robić w lokalnych.
Wszędzie, gdzie użycie deklaracji wpływa tylko na ograniczoną i wyraźnie widoczną część kodu, jest to całkowicie akceptowalne.
Gdy zanieczyszczasz kontekst globalny, wpływa to na niepowiązany kod (domyślnie za pomocą nagłówka). Nic się nie dzieje, gdy robisz to w kontekście lokalnym.
źródło
Zrobiłeś. To zalecenie dotyczy tylko
using namespace
dyrektywy (która jest powszechnie nazywanaabusing namespace
, nie do końca dowcipnie). Zdecydowanie zaleca się stosowanie w pełni kwalifikowanej nazwy funkcji lub obiektu, na przykładstd::cout
.źródło
Chociaż pytanie ma już przydatne odpowiedzi, jeden szczegół wydaje się zbyt krótki.
Większość programistów jest na początku trochę mylona ze
using
słowem kluczowym i opisaminamespace
użycia, nawet jeśli próbują się tego nauczyć, przeglądając odniesienie, ponieważ deklaracja i dyrektywa brzmią w pewnym stopniu równoważnie, oba są stosunkowo abstrakcyjnymi długimi słowami zaczynającymi się na d .Identyfikatory w przestrzeniach nazw są dostępne poprzez jawne nazwanie przestrzeni nazw:
może to być o wiele więcej kluczy do pisania. Ale może również zmniejszyć znaczenie twojego kodu, jeśli większość identyfikatorów zostanie prefiksowanych w ten sam sposób. Słowo
using
kluczowe pomaga zapobiegać tym negatywnym stronom przestrzeni nazw. Odusing
działa na poziomie kompilatora (nie ma makra), jego efekt trwa przez cały zakres, w którym jest używany. Dlatego styl Google ogranicza jego użycie do dobrze zdefiniowanych zakresów, tj. Klas w plikach nagłówkowych lub funkcji w plikach CPP.... oczywiście istnieje różnica między używaniem deklaracji
i stosując dyrektywę
Jeśli jest stosowany w ogromnych zakresach, ten ostatni prowadzi do znacznie większego zamieszania.
źródło
Proszę bardzo:
Pisząc to w ten sposób, unikamy podatnych na błędy ADL wraz z używaniem dyrektyw i deklaracji.
To ma być sarkastyczna odpowiedź. :-RE
W tej sprawie jestem z Herbem Sutterem nad Google. Z standardów kodowania C ++:
Możesz mieć obsesję na punkcie potencjalnych konfliktów przestrzeni nazw, które prawdopodobnie nigdy się nie pojawią i prawdopodobnie nie będą trudne do naprawienia w tak rzadkim astronomicznie wydarzeniu, ostrożnie unikając
using
dyrektyw i wyraźnie określając każdą rzecz, której używasz (w zależności od operatora) wraz zusing
deklaracjami lub po prostu idź i zacznijusing namespace std
. Polecam to drugie z punktu widzenia produktywności.Przeciwnie, jeśli mnie zapytasz, i uważam, że Sutter powyżej się zgadza.
Teraz w trakcie mojej kariery napotkałem łącznie około 3 konfliktów przestrzeni nazw, będących bezpośrednim wynikiem
using
dyrektyw w bazach kodów obejmujących dziesiątki milionów LOC. Jednak we wszystkich 3 przypadkach znajdowały się one w plikach źródłowych, które obejmowały ponad 50 000 wierszy starszego kodu, pierwotnie napisane w C, a następnie zamaskowane na C ++, wykonując ogromną eklektyczną listę różnych funkcji, w tym nagłówki z kilkunastu różnych bibliotek i posiadające epicka lista#includes
obejmująca całą stronę. Pomimo epickiego bałaganu nie były zbyt trudne do naprawienia, ponieważ powodowały błędy kompilacji w OSX (tym, w którym nie udało się zbudować kodu), a nie błędy w czasie wykonywania. Nie organizuj swojego kodu w ten koszmarny sposób i wszystko powinno być w porządku.To powiedziawszy, unikaj zarówno
using
dyrektyw, jak i deklaracji w plikach nagłówkowych. To po prostu opóźnione. Ale w przypadku plików źródłowych, a zwłaszcza tych, które nie mają całej strony wypełnionej#include
dyrektywami, powiedziałbym, że nie przejmuj się, jeśli nie pracujesz dla Google.źródło