Технически вам может потребоваться использовать , используя (для целых пространств имен или отдельных имен), чтобы иметь возможность использовать Argument Dependent Lookup.
Рассмотрим две следующие функции, которые используют swap()
.
#include <iostream>
#include <algorithm>
namespace zzz
{
struct X {};
void swap(zzz::X&, zzz::X&)
{
std::cout << "Swapping X\n";
}
}
template <class T>
void dumb_swap(T& a, T& b)
{
std::cout << "dumb_swap\n";
std::swap(a, b);
}
template <class T>
void smart_swap(T& a, T& b)
{
std::cout << "smart_swap\n";
using std::swap;
swap(a, b);
}
int main()
{
zzz::X a, b;
dumb_swap(a, b);
smart_swap(a, b);
int i, j;
dumb_swap(i, j);
smart_swap(i, j);
}
dumb_swap
всегда вызывает std::swap
- хотя мы бы предпочли использовать zzz::swap
для zzz::X
объектов.
smart_swap
делает std::swap
видимым как запасной вариант (например, при вызове с целыми числами), но, поскольку он не полностью определяет имя, zzz::swap
будет использоваться через ADL для zzz::X
.
Субъективно, что заставляет меня использовать using namespace std;
- это написание кода, который использует все виды стандартных функциональных объектов и т. Д.
//copy numbers larger than 1 from stdin to stdout
remove_copy_if(
std::istream_iterator<int>(std::cin), std::istream_iterator<int>(),
std::ostream_iterator<int>(std::cout, "\n"),
std::bind2nd(std::less_equal<int>(), 0)
);
IMO, в таком коде std::
просто создает помехи в линии.
Я бы не нашел using namespace std;
отвратительным преступлением в таких случаях, если бы оно использовалось в файле реализации (но его можно даже ограничить областью действия функции, как в примере с подкачкой).
Определенно не помещайте оператор using в заголовочные файлы. Причина в том, что это загрязняет пространство имен для других заголовков, которые могут быть включены после вызывающего, что может привести к ошибкам в других заголовках, которые могут не находиться под вашим контролем. (Это также добавляет фактор удивления: люди, включающие файл, могут не ожидать, что будут видны все виды имен.)