2009-11-02 6 views
23

Wydaje mi się, że używanie niezasilanych przestrzeni nazw po prostu wymaga kłopotów, gdy ktoś wprowadzi nowy obszar nazw, który ma tę samą nazwę co przestrzeń nazw poziomu głównego i w tajemniczy sposób zmienia znaczenie wielu programów. Dlaczego ludzie zawsze mówią: std:: zamiast ::std::. Czy naprawdę chcą powiedzieć: "Chcę użyć wszystkiego, co jest przydatne pod std, a nie root".Dlaczego wszyscy używają niezatwierdzonych deklaracji przestrzeni nazw (np. Std :: not :: std: :)?

Oto przykład tego, co mam na myśli:

W fred/Foo.h:

#include <string> 

namespace fred { 

class Foo { 
public: 
    void aPublicMember(const std::string &s); 
}; 

} // end namespace fred 

W fred/Bar.h:

namespace fred { 
namespace std { // A standard fred component 

class string { // Something rather unlike the ::std::string 
    // ... 
}; 

} // namespace std 

class Bar { 
public: 
    void aPublicMember(std::string &s); 
}; 

} // namespace fred 

W oops.cpp:

#include <string> 
#include "fred/Bar.h" 
#include "fred/Foo.h" // Oops, the meaning of Foo is now different. 

Czy tego chcą ludzie? Brakuje mi czegoś?

A może mówisz, że nigdy nie powinieneś nazwać przestrzeni nazw std. A to wszystko dobrze i dobrze, ale co z inną przestrzenią nazw poziomu root? Czy jakikolwiek obszar nazw poziomu root, który kiedykolwiek zdefiniowałby gdziekolwiek, zawsze będzie niedostępny dla nazwy podprzestrzeni?

Aby wyjaśnić, nie będę rozważać żadnej odpowiedzi, która mówi mi, że std jest wyjątkowy, ponieważ po prostu użyłem go jako przykładu. Mówię o ogólnym problemie i używam go jako rekwizytów do zilustrowania go, chociaż przyznaję, że to dość zaskakująca podpórka.

Odpowiedz

14

Powodem praktycznym dla niezajęzykowych obszarów nazw jest zwykle wystarczający jeden poziom przestrzeni nazw. Gdy nie jest, zwykle używa się drugiego poziomu dla szczegółów implementacji. I na koniec, nawet przy użyciu wielu poziomów, są one zwykle określone niejawnie z poziomu root. to znaczy. nawet w przestrzeni nazw ns1, zazwyczaj odwołujesz się do ns1::ns2::foo zamiast ns2::foo lub ::ns1::ns2::foo.

Z tych trzech powodów formularz ::ns1 jest w normalnych przypadkach zbędny. Jedyny przypadek, w którym bym to rozważył, byłby w zgłoszeniach do Boost, ponieważ jako autor Boost nie będę wiedział, gdzie moje oprogramowanie będzie używane.

+0

Mam zamiar zaakceptować to, ponieważ jest najbliżej prawdziwej odpowiedzi. Myślę, że ten drugi został właśnie wybrany wyżej, ponieważ był zabawniejszy. :-) Podejrzewam, że powinienem był wybrać inny przykład lub nie zadać tego pytania tak, jak ja to zrobiłem. – Omnifarious

2

W przypadku std nie przyjąłbym żadnej innej przestrzeni nazw o tej samej nazwie, tych samych klasach, ale o innym znaczeniu.

W innych przypadkach czołowy model :: wygląda nieprzyjemnie i utrudnia czytanie kodu (moim zdaniem). Spory w przestrzeni nazw są zbyt rzadkie, aby umieścić wszystko przed wszystkim.

3

To tyle sztuczny:

namespace fred { 
namespace std { // A standard fred component 

class string { // Something rather unlike the ::std::string 
    // ... 
}; 

} // namespace std 
} // namespace fred 

To Fred nie byłby w stanie wyjaśnić, dlaczego to zrobił dla całego zespołu.

Aby odpowiedzieć na twoje pytanie: ludzie pomijają pierwsze "::", ponieważ jest to nawyk, który oszczędza czas i ponieważ łatwiej jest oczekiwać, że gdy przestrzeń nazw jest używana gdziekolwiek, wtedy taka nazwa jest absolutna, a nie względna.

+3

Fred musi trafić w LART. – user7116

7

dlaczego ludzie zawsze powiedzieć std ::

Nie zawsze. Używam string i using ::std::string. Więc nic złego, jeśli będzie fred::std::string, ponieważ nadal używam std::string. W małych plikach cpp może to być nawet using namespace ::std.Próbka:

#include <iostream> 
using ::std::string; 
//using namespace ::std; // good for small cpp-files 

int main() 
{ 
    string s = "sometext"; // no leading ::std 
} 

nigdy nie należy po prostu wymienić namespace std

Tak, nie należy podać nazwę std do niestandardowej przestrzeni nazw.

2

Wiele kodu jest zapisanych w globalnej przestrzeni nazw. Jeśli ktoś naprawdę zredefiniuje :: std ::, nie będzie miało znaczenia, jak się do niego odwołujesz w tego rodzaju kodzie.

Twój scenariusz jest mało prawdopodobny i łatwy w obsłudze. Po pierwsze, konwencja, ponieważ istniał "std", polegała na tym, że nie używa się tej nazwy. Po drugie, jeśli było spotkać pakiet, który zdefiniował nazw std „”, po prostu to zrobić:

#include <package_name.hpp> 

namespace package_name { 
    using namespace std; 
} 

namespace my_app { 
    class my_class : public package_name::class_of_something {}; 
} 

lub coś podobnego. Być może będziesz musiał jawnie nazwać :: std jako standardowe. Chodzi mi o to, że ludzie ciągle używają un-zakotwiczonego "std ::", ponieważ nawet najgorsze konsekwencje nie są wielką sprawą i są mało prawdopodobne.

2

OK, mówisz, że std to tylko przykład. Ale wydaje mi się, że twoje pytanie dotyczy tylko przypadku, w którym ktoś robi coś tak złego jak przesadne std.

Pozwól mi przedstawić inny przykład:

namespace logging 
{ 
    // Logs to local file 
} 

namespace server 
{ 
    namespace logging 
    { 
     // Logs to remote destination 
    } 
} 

namespace client 
{ 
    namespace logging 
    { 
     // Logs to local file and to screen 
    } 
} 

w tym przypadku, nie poprzedzenie :: wyniki w domyślnym zachowaniem.

+0

Jest to doskonały powód, dla którego względne przestrzenie nazw powinny być używane w pewnych okolicznościach, zdecydowanie się zgadzam. – Omnifarious

+0

Co jednak dzieje się w twojej klasie, gdy ktoś tworzy "serwer" przestrzeni nazw w przestrzeni nazw "klient", aby odnieść się do spraw związanych z serwerem, o które dba klient? – Omnifarious

+0

@Wielo chciałem pokazać, że odpowiedzi w dużej mierze zależą od tego, jaki przykład podasz dla tego pytania. W każdym razie: Powiedziałbym, że byłoby to prawie tak złe, jak wymyślanie własnego std namespace. Można użyć "servercom", jeśli chodzi o komunikację lub "serverconf" dla konfiguracji itd. Zamiast po prostu "serwer". – foraidt

33

Więc dlaczego ludzie zawsze powiedzieć std :: zamiast :: std ::

Prawdopodobnie dlatego, że tak naprawdę nigdy nie miał problemów z dwuznaczności tego powodu.

W tym samym wierszu: nigdy nie musiałem podawać "ziemi" w moim adresie, a nie zamierzam.

Musisz narysować gdzieś linię, a to jest rozsądne założenie, że inni nie będą tworzyć własnych przestrzeni nazw, lub przynajmniej, że biblioteka, która nie będzie bardzo popularna. :)

+0

+1 dla humoru [15 char filler] – foraidt

+2

* chichot * Cóż, gdybym żył w Andromedzie i chciałem odnieść się do kogoś na Ziemi, prawdopodobnie opuściłbym "lokalną grupę", ale chciałbym dodać "Drogę mleczną" , "System Sol" i "Ziemia". – Omnifarious

+2

, ale ludzkość musi ewoluować techno z tego rocka zanim to będzie problemem – Hardryv

1

W ten sam sposób, w jaki zarezerwowane są nazwy z prefiksem _, należy rozważyć std:: tak dobrze, jak zarezerwowano.

+0

Chociaż nie jest to pedantyczny, nie wszystkie nazwy poprzedzone podkreślnikiem są zastrzeżone. – GManNickG

+0

Tak, nie wszystkie. Czy ktokolwiek powinien być zainteresowany w pełni gorliwością, [przeczytaj to] (http://stackoverflow.com/questions/228783/what-are-the-rules-about-using-an-underscore-in-a-c-identifier) –

Powiązane problemy