Jest jeden (co prawda, nieco rzadkością) sytuacja, w której forma korzystania naprawdę może zrobić różnicę, a forma chcesz użyć jestusing namespace foo
, i to najczęściej stosowany do nazw std
(czyli gdzie piszesz using namespace std;
.
najbardziej oczywistym przykładem jest to, że piszesz sortowania typu zdefiniowanego przez użytkownika. to możliwe że zostanie zastosowana do typu, dla którego użytkownik również zdefiniowany ma swoją własne swap
.
Utkniesz w sytuacji, w której chcesz użyć swapu, jeśli go zdefiniowałeś, ale użyjesz std :: swap, jeśli go nie zdefiniował. Jeśli użyjesz std::swap
bezpośrednio w kodzie, to skończysz używając std::swap
, nawet jeśli typ ma zdefiniowaną własną zamianę. Odwrotnie, twój kod nie skompiluje się, jeśli bezpośrednio określisz swap specjalnie dla tego typu i żaden nie zostanie dostarczony.
Aby obejść ten problem, możesz zrobić coś takiego:
using namespace std;
template <class Iter>
void my_sort(Iter first, Iter last) {
// ...
if (*last < *first)
swap(*first, *last);
}
ten znajdzie swap specjalnie dla danego typu porównywanych (tj swap
zdefiniowane w tej samej przestrzeni nazw, jak tego typu), jeżeli istnieje jeden (poprzez wyszukiwanie zależne od argumentu) i std::swap
, jeśli żaden nie jest zdefiniowany dla typu (przez using namespace std;
).
Może to mieć wpływ na wydajność - jeśli napisali swap specjalnie dla swojego typu, możesz ogólnie oczekiwać, że dzięki temu mogą zapewnić lepszą wydajność. Oznacza to, że jawne określenie std::swap
może działać, ale prawdopodobnie doprowadzi do gorszej wydajności.
W przeciwnym razie jest to prawie wyłącznie kwestia wygody i czytelności - ja najczęściej wolę podawać pełne nazwy (np. std::swap
) z wyjątkiem sytuacji jak powyżej, gdzie (w czasie, kiedy piszę kod) albo co najmniej dwie możliwości mogą być preferowane i chcę dać kompilatorowi wystarczającą swobodę wyboru właściwego.
Innym razem, gdy używam deklaracji/dyrektyw, przydatne jest, gdy przestrzenie nazw stają się naprawdę głęboko zagnieżdżone. Zwiększenie (dla jednego oczywistego przykładu) ma kilka nazw, które byłyby zbyt długie dla wygodnego użycia, jeśli używałbyś w pełni kwalifikowanej nazwy za każdym razem. Dotyczyło to szczególnie biblioteki Boost Lambda (teraz, na szczęście, w większości przestarzałej), w której użyłeś symboli zastępczych, takich jak _1
, które skończyłyby się jako coś w rodzaju boost::lambda::placeholders::_1
(ale wychodzę z pamięci, więc prawdopodobnie jest to co najmniej częściowo błędne) jeśli nalegałeś na używanie w pełni kwalifikowanej nazwy. To pokonałoby dużą część celu używania biblioteki lambda w pierwszej kolejności.
Nie jest to związane z wydajnością środowiska wykonawczego. –
Powiedziano mi, gdy byłem na studiach, że oprócz posiadania przestrzeni nazw w zakresie, używanie 'using namespace std;' również było pułapką bezpieczeństwa. –
1. Odradza się z powodów, które opisujesz 2. Pomaga w korzystaniu z funkcji udostępnianych przez innych w ich własnych przestrzeniach nazw przy pomocy ADL (patrz 'std :: swap', ale niech odpowiedź lepiej ci to wytłumaczy) 3. Wolę większość, ale to kwestia gustu i może być uciążliwa, jeśli nie lubisz oglądać "std ::" wszędzie, jak ja. Ale żadna z nich nie ma różnic w wydajności, chodzi tylko o rozpoznawanie nazw i nie "" wkomponowuje się w rzeczywisty kod "*. –