There is one (admittedly, somewhat uncommon) situation in which the form you use really can make a difference, and the form you want to use is using namespace foo
, and it's most commonly applied to the std
namespace (i.e., where you write using namespace std;
.
The most obvious example is that you're writing a sort for a user-defined type. It's possible that this will be applied to a type for which the user has also defined their own swap
.
You're stuck with a situation where you want to use their swap if they've defined one, but use std::swap if they haven't defined one. If you use std::swap
directly in your code, then you'll end up using std::swap
even if the type has a swap of its own defined. Conversely, your code will fail to compile if you directly specify a swap specifically for the type, and none has been supplied.
To get around this, you do something like:
using namespace std;
template <class Iter>
void my_sort(Iter first, Iter last) {
// ...
if (*last < *first)
swap(*first, *last);
}
This will find the swap specifically for the type being compared (i.e., a swap
defined in the same namespace as that type), if there is one (via argument dependent lookup), and std::swap
if none is defined for the type (via the using namespace std;
).
This can have an impact on performance -- if they've written a swap specifically for their type, you can generally expect that it's because by doing so, they can provide better performance. That means that explicitly specifying std::swap
may work, but will probably lead to inferior performance.
Otherwise, it's almost entirely a matter of convenience and readability -- I mostly prefer giving the full names (e.g., std::swap
) except in a situation like above, where (at the time that I'm writing the code) either of at least two possibilities might be preferred, and I want to give the compiler sufficient leeway to pick the right one.
The other time I find using declarations/directives useful is when namespaces get really deeply nested. Boost (for one obvious example) has some names that would be way too long for convenient use if you used the fully qualified name every time. This was especially true for the (now, thankfully, mostly obsolete) Boost Lambda library, where you used placeholders like _1
, that would have ended up as something like boost::lambda::placeholders::_1
(but I'm going from memory, so that's probably at least partly wrong) if you insisted on using a fully qualified name. That would have defeated a large part of the purpose of using the lambda library in the first place.