scope of using declaration within a namespace
No, it is not safe - it won't pollute another namespace, but it is dangerous for other reasons:
A using
directive will import anything that is currently visible by the name you specify into the namespace where you use it. While your using
will only be visible to users of MyNamespace
, other things from "outside" will be visible to your using
declaration.
So how is this dangerous when used in a header? Because it will import things that are visible at the point of the declaration, the exact behavior will depend on the order of headers you include before the declaration (There might be different things visible from boost::numeric::ublas::vector
). Since you cannot really control which headers are included before your header (nor should you be! headers should be self-sufficient!), this can lead to very strange problems where your function will find one thing in one compilation unit, and another in the next.
As a rule of thumb, using
declarations should only be used after all includes in a .cpp file. There's also an item on this exact issue in the book "C++ Coding Standards" by Sutter and Alexandrescu (Item 59). Here's a quote:
But here's the common trap: Many people think that using declarations issued at namespace level (...) are safe. They are not. They are at least as dangerous, and in a subtler and more insidious way.
Even when it's unlikely that the name you are using
doesn't exist anywhere else (as is probably the case here), things can get ugly: In a header, all declarations should be fully qualified. This is pain, but otherwise, strange things can happen.
Also see Migrating to Namespaces, Using-declarations and namespace aliases and Namespace Naming for examples and the problem described in-depth.
Scope of `using namespace` within another namespace
The standard says that (7.3.4/2)
A
using-directive
specifies that the names in the nominated namespace can be used in the scope in which the
using-directive
appears after the
using-directive
.
namespace A { \
int i = 9; | <-- namespace A scope.
} /
namespace B { \
using namespace A; | <-- namespace B scope. "i" is visible after
void bar() | the "using namespace" line.
{ |
i += 1; /*Ok*/ |
} |
} /
namespace B { \
void foo() |
{ | <-- still namespace B scope. "i" is still visible
i += 1; /*Ok*/ |
} |
} /
So stuff made visible with this using directive will be visible everywhere in A scope after the using namespace B
line. Of course, if you do this in a header file, all the stuff will be visible everywhere where you include that header file, so you should not really use "using namespace..." anywhere in the headers.
What's the scope of the using declaration in C++?
When you #include a header file in C++, it places the whole contents of the header file into the spot that you included it in the source file. So including a file that has a using
declaration has the exact same effect of placing the using
declaration at the top of each file that includes that header file.
Scope a using declaration, inside a header
Try declaring the types in an embedded namespace inside thirdparty
so that the macro is happy, then alias that namespace so that it's accessible globally:
namespace thirdparty::myns {
TP_MACRO(my_type_name, inner);
}
namespace myns = thirdparty::myns;
If you are not using C++17, then use:
namespace thirdparty {
namespace myns {
TP_MACRO(my_type_name, inner);
}
}
Trying to define namespace member via using-declaration
Current working draft N4527, [8.3p1]:
[...] When the declarator-id is qualified, the declaration shall refer to a
previously declared member of the class or namespace to which the
qualifier refers (or, in the case of a namespace, of an element of the
inline namespace set of that namespace (7.3.1)) or to a specialization
thereof; the member shall not merely have been introduced by a
using-declaration in the scope of the class or namespace nominated by
the nested-name-specifier of the declarator-id. [...]
So, definitely ill-formed; GCC and MSVC are wrong.
Related Topics
Do All Pointers Have the Same Size in C++
C++11 Static_Assert and Template Instantiation
Why Doesn't Reference-To-Member Exist in C++
Cuda How to Get Grid, Block, Thread Size and Parallalize Non Square Matrix Calculation
Function Prologue and Epilogue in C
Is Std::Vector Memory Freed Upon a Clear
Why Does C++ Not Have a Const Constructor
How to Redirect Output to a File with Createprocess
Inaccessible Direct Base' Caused by Multiple Inheritance
What Does This Variadic Template Code Do
What Is the Maximum Length in Chars Needed to Represent Any Double Value
Preincrement Faster Than Postincrement in C++ - True? If Yes, Why Is It
C++ Undefined Reference to Vtable and Inheritance
Can Std::Begin Work with Array Parameters and If So, How
Division by Zero: Undefined Behavior or Implementation Defined in C And/Or C++