问题
Two ways to use the using declaration are
using std::string;
using std::vector;
or
using namespace std;
which way is better?
=========Satisfactory Answer Below=============
In short, using declarations within functions are harmless provided locally scoped care is given whereas global using declarations are dangerous as they could cause namespaces to intersect, thereby confusing the compiler.
Often we like to use every name from a namespace without qualification. That can be achieved by providing a using-declaration for each name from the namespace, but that's tedious and requires extra work each time a new name is added to or removed from the namespace. Alternatively, we can use a using-directive to request that every name from a namespace be accessible in our scope without qualification. [...] [...] Using a using-directive to make names from a frequently used and well-known library available without qualification is a popular technique for simplifying code. This is the technique used to access standard-library facilities throughout this book. [...] Within a function, a using-directive can be safely used as a notational convenience, but care should be taken with global using-directives because overuse can lead to exactly the name clashes that namespaces were introduced to avoid. [...] Consequently, we must be careful with using-directives in the global scope. In particular, don't place a using-directive in the global scope in a header file except in very specialized circumstances (e.g. to aid transition) because you never know where a header might be #included.
Credit to Jonathan Wakely for the quote.
回答1:
It depends.
If you want to inject a single name into another scope, the using-declaration is better, e.g.
namespace foolib
{
// allow vector to be used unqualified within foo,
// or used as foo::vector
using std::vector;
vector<int> vec();
template<typename T> struct Bar { T t; };
template<typename T>
void swap(Bar<T>& lhs, Bar<T>& rhs)
{
using std::swap;
// find swap by ADL, otherwise use std::swap
swap(lhs.t, rhs.t);
}
}
But sometimes you just want all names, which is what a using-directive does. That could be used locally in a function, or globally in a source file.
Putting using namespace
outside a function body should only be done where you know exactly what's being included so it's safe (i.e. not in a header, where you don't know what's going to be included before or after that header) although many people still frown on this usage (read the answers at Why is "using namespace std" considered bad practice? for details):
#include <vector>
#include <iostream>
#include "foolib.h"
using namespace foo; // only AFTER all headers
Bar<int> b;
A good reason to use a using-directive is where the namespace only contains a small number of names that are kept intentionally segregated, and are designed to be used by using-directive:
#include <string>
// make user-defined literals usable without qualification,
// without bringing in everything else in namespace std.
using namespace std::string_literals;
auto s = "Hello, world!"s;
So there is no single answer that can say one is universally better than the other, they have different uses and each is better in different contexts.
Regarding the first usage of using namespace
, the creator of C++, Bjarne Stroustrup, has this to say in §14.2.3 of The C++ Programming Language, 4th Ed (emphasis mine):
Often we like to use every name from a namespace without qualification. That can be achieved by providing a
using
-declaration for each name from the namespace, but that's tedious and requires extra work each time a new name is added to or removed from the namespace. Alternatively, we can use ausing
-directive to request that every name from a namespace be accessible in our scope without qualification. [...]
[...] Using ausing
-directive to make names from a frequently used and well-known library available without qualification is a popular technique for simplifying code. This is the technique used to access standard-library facilities throughout this book. [...]
Within a function, ausing
-directive can be safely used as a notational convenience, but care should be taken with globalusing
-directives because overuse can lead to exactly the name clashes that namespaces were introduced to avoid. [...]
Consequently, we must be careful withusing
-directives in the global scope. In particular, don't place ausing
-directive in the global scope in a header file except in very specialized circumstances (e.g. to aid transition) because you never know where a header might be#include
d.
To me this seems far better advice than just insisting it is bad and should not be used.
回答2:
using std::string;
and using std::vector;
.
Polluting the global namespace with a bunch of symbols is a bad idea. You should just use the std
namespace prefix too, so you know that you're using standard library containers. Which is better than both options IMO.
If you are simply using the standard library and nothing else and never will be adding in any other libraries to your project, by all means, use using namespace std;
- Whatever you feel more comfortable with in that situation. The convention of "never use using namespace std;
" comes from the fact that multiple other libraries define things such as string
, vector
and such. It is good practice to never import the whole namespace, but it should cause no bothers in your case.
来源:https://stackoverflow.com/questions/31450129/using-stdtype-v-s-using-std-namespace