While reading from Bruce Eckel's "Thinking in C++" about namespaces, I encountered the following statement:
However you'll virtually never see a using directive in a header file (at least not outside of scope). The reason is that using directive eliminate the protection of that particular namespace, and the effect last until the end of current compilation unit. If you put a using directive (outside of a scope) in a header file, it means that this loss of "namespace protection" will occur within any file that include this header, which often mean other header files.
Would you please like to help me to comprehend the above statement with some easy example?
You should definitely NOT use using namespace in headers for precisely the reason you say, that it can unexpectedly change the meaning of code in any other files that include that header. There's no way to undo a using namespace which is another reason it's so dangerous.
Code in header files should always use the fully qualified namespace name. The following example shows a namespace declaration and three ways that code outside the namespace can accesses their members.
The statement using namespace std is generally considered bad practice. The alternative to this statement is to specify the namespace to which the identifier belongs using the scope operator(::) each time we declare a type.
Since you can't put a namespace using statement at the top level of the header file, you must use a fully qualified name for Standard Library classes or objects in the header file. Thus, expect to see and write lots of std::string, std::cout, std::ostream, etc. in header files.
Consider this program:
line# 1 #include <string> 2 3 using namespace std; 4 5 struct string { const char* p; }; // Beware: another string! 6 7 int main() 8 { 9 string x; // Error: ambiguous - which string is wanted? 10 }
If you try to compile it, you'll see errors:
g++ using.cc -o using using.cc: In function `int main()': using.cc:9: error: use of `string' is ambiguous using.cc:5: error: first declared as `struct string' here /usr/lib/gcc/i386-redhat-linux/3.4.6/../../../../include/c++/3.4.6/bits/stringfwd.h:60: error: also declared as `typedef struct std::basic_string<char, std::char_traits<char>, std::allocator<char> > std::string' here using.cc:9: error: `string' was not declared in this scope using.cc:9: error: expected `;' before "x"
The problem here is that when main()
specifies string x;
, the compiler's not sure whether the user-defined ::string
or included std::string
is wanted.
Now imagine you take the top part of the program... lines 1 through 5 - up to and including the struct string
... and put it into a header file which you then #include
before main()
. Nothing changes: you still have an error. So, just as for standalone programs, header files with using
statements in them can cause trouble for other code that includes them, making some of their statements ambiguous.
It can be a bigger pain though, as headers can be included - directly or indirectly - by arbitrarily huge amounts of dependent code, and...
using
statement from the header, or<string>
, or any other header affecting std::
...might break code including the problematic header. Either problem may render dependent code uncompilable, and issues may not even be noticed until another compilation is attempted. Further, the person suffering due to the using
statement may not have filesystem/code-repository permissions, corporate authority etc. to remove the using
statement from the header, nor fix other affected client code.
That said, if a header only has "using" inside a class or function, then there's no affect on code beyond that scope, so the potential impact of changes to std:: is dramatically reduced.
If a header contains using namespace std
, everything from that namespace is added the global namespace in every module that includes the header.
This means you can never declare a function or define a class with the same name (and compatible parameters for a function) as an std
function/class in the global namespace in any of those modules.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With