what is the use of using declaration type of namespacing over using directive type of namespacing??when to use each one of them?
The declaration type of namespace directive introduces selected named symbols into your code scope (and leaves other symbols from the same namespace inaccessible without the namespace qualifier).
The using type of namespace directive introduces all symbols from the namespace into your code scope - which means you don't necessarily know exactly which symbols were introduced (there could have been undocumented symbols, or symbols left over from previous versions of the library, or ...).
- For control, use the declaration type of namespace directive.
- For convenience (with risk), use the using type of namespace directive.
Besides the using declaration allowing access to a symbol rather than a namespace, the using declaration also brings the symbol to the scope of the declaration. The using directive only affects lookup.
Jonathan already resumed the differences between using namespace foo;
and using foo::Bar;
but I think his answer is unfortunately incomplete.
First: using namespace
should never appear in a header file. By doing so you might render it impossible to use in combination with other header files because of a symbol clash...
Second: in general, you should try to limit the scope of the symbols as much as possible, you probably already do it while writing code:
for (size_t i = 0; i < 5; ++i)
{
std::string myString = myVec.at(i);
if (myString == "Foo") { std::cout << "Found"; break; }
}
Here it would be useless (and polluting) to have myString
declared outside the for
loop. In fact, that very advice can be found in a number of books:
From Scott Meyers' Effective C++, Item 26: Postpone variable definitions as long as possible.
From Herb Sutter and Andrei Alexandrescu's C++ Coding Standard, Item 18: Declare variables as locally as possible
There is no reason not to do the same with using
declarations.
Third: consider alternatives to using
: namespace aliasing and typedef
.
// foo.h
class Foo
{
public:
std::vector<std::string> getSynonyms(const std::string& s) const;
private:
typedef std::map< std::string, std::vector<std::string> > synonyms_type;
synonyms_type mSynonyms;
};
// foo.cpp (never in header, at general scope)
namespace fu = boost::fusion;
std::vector<std::string> Foo::getSynonyms(const std::string& s) const
{
synonyms_type::const_iterator it =
std::find(mSynonyms.begin(), mSynonyms.end(), s);
std::vector<std::string> result;
if (it != mSynonyms.end()) { result = it->second; }
return result;
}
What are the advantages ?
- namespace aliasing > reduce typing almost as much without injecting the types right in the current scope so without risk
- typedef > reduce typing more than
using
and allow easy change of underlying type too.