How do nested namespaces work? - c++

The Arguments class is defined in the v8::internal namespace
https://github.com/joyent/node/blob/master/deps/v8/include/v8.h#L113
namespace v8 {
// ...
namespace internal {
class Arguments;
}
// ...
}
However, it is later used in the v8 namespace to access it
https://github.com/joyent/node/blob/master/src/handle_wrap.h#L38
using v8::Arguments;
Which leads me to to the question "How do nested namespaces work?".

They work as you would expect. Consider that a single-level namespace (e.g. std::) is already nested in the global namesapce ::. Unless a using namespace std; directive is applied, only the std name is registered in the global namespace and symbols in std:: are not directly visible to the global namespace.
Add the second layer and apply the same logic. Symbols in v8::internal are not directly accessible in either the global namespace or v8::, but a using namespace v8; directive will pull v8 symbols including internal:: (the namespace name, not its contents) into the global namespace etc.
As you surely know, there are other ways to pull a single name into another namespace: using directives and typedef directives. Unless there is another class named v8::Arguments, there is a typedef or using directive pulling v8::internal::Arguments into v8:: as v8::Arguments.
A quick look at the V8 source code in node.js, there is indeed a class named v8::Arguments defined in namespace v8:: at line 1946 and namespace v8::internal:: is not opened until line 3709.

Related

C++ "Using" in Modules

One of the reasons "using namespace" in header files is considered bad practise (Why is "using namespace std;" considered bad practice?) is because it "leaks" the using-directive to everyone that includes your headerfile. Is this still the case for C++ modules or can I "safely" put e.g. using namespace std or using std::cout into my module? :
module;
#include <iostream>
export module Module;
using namespace std;
// using std::cout;
export void greet() {
cout << "Hello World!\n";
}
The scope of any using declaration of this sort is the translation unit being compiled. All module files (a file that starts with some form of module declaration) is a separate translation unit. So it will be just like any other non-exported declaration in your module: local to it.
That having been said, this is only one reason to avoid using namespace std; there are many others. It can play havoc with name lookup. The included names can clash with global names and names used in your namespace. And so forth.
However, employing using declarations for specific components of the std namespace is a lot more reasonable, as the primary reason not to do so is to prevent leakage. Also, namespace aliases are a good idea too, for sub-namespaces like std::chrono, std::filesystem, and the like.

Scope a using declaration, inside a header

Unfortunately I'm bound to using a thirdparty macro which assumes that I am within the namespace thirdparty. However this macro declares some types which I need to be outside of the thirdparty namespace, so I can't use this snippet:
namespace thirdparty
{
TP_MACRO(my_type_name, inner);
}
If I did, all of my declared types would be in the thirdparty:: namespace which won't work.
The issue is that the TP_MACRO is using types from inside of the thirdparty namespace without qualifying them. To get arround the this I am currently bringing these types into the current scope with using declarations:
using thirdparty::type1;
using thirdparty::type2;
TP_MACRO(my_type_name, inner);
The downside of this approach is that I'm polluting the global namespace with these types, which is generally bad practice (this code is in a header file).
I can wrap the above snippet in a new namespace (which I am doing), but I would like to know if there is a way to scope these using declarations so that after the macro has declared my types, I can remove them from the surrounding namespace?
The TP_MACRO is similar to (but is more complex in reality):
#define TP_MACRO (name, inner) \
typedef type1<inner> type1_##name; \
typedef type2<inner> type2_##name;
It is also subject to change, hence why I would avoid copying it's contents.
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);
}
}
I can wrap the above snippet in a new namespace (which I am doing)
That's what you should be doing.
I would like to know if there is a way to scope these using declarations so that after the macro has declared my types, I can remove them from the surrounding namespace?
No.
Also I suggest making a recommendation upstream that they improve these macros.

using standard namespace in C plus plus

Consider this
#include<headerfile1>
#include<headerfile2>
.
.
#include<headerfilen>
using namespace std;
when I write this(header files are all in standard library of C++),does std namespace of all header files come into picture?
Also, if there are two libraries h1 and h2 and both have same namespace x and in those namespaces have same function func(). How do I resolve this?
From cppreference:
A using-directive that names the inline namespace is implicitly
inserted in the enclosing namespace (similar to the implicit
using-directive for the unnamed namespace).
For instance, in the following example, using namespace std::string_literals makes the operator visible inside the scope:
{ // in C++14, std::literals and its member namespaces are inline
using namespace std::string_literals; // makes visible operator""s
// from std::literals::string_literals
auto str = "abc"s;
}
If you use the using directive outside a scope (for instance as in your example), pain will follow, as the commenters stated, especially if this file is a header file: this namespace will be implicitly imported to any file that includes this one. This is why the proper way of managing a big project is to create your own namespace and put all your custom objects in that new namespace. If you really must use a using directive, do so in the implementation file, never in the header, and ideally within scopes.
This will help you avoid most conflicts, unless your namespace uses a common name:
namespace Matrix{ <--- Bad practice, Matrix will probably conflict with something
myStuff ...
}
namespace JohnsAwesomeMatrix236790{ <--- Namespace name is unique,unlikely to get conflicts.
myStuff ...
}
Also, it is much safer to import the few functions that you use instead of the entire namespace:
using namespace std; // Imports the entire namespace!
using std::cout; // Much better, we only import
using std::endl; // the names of the two functions we use a lot
Any decently written library you include will make very careful use of the using directive (if at all), so you normally don't have to worry about this. However, if you use code written with less stringent standards (e.g., scientific code) this is something to look out for.

Using string literals without using namespace std

There's recommendation in C++ community to not to use using namespace std;. But suppose you want to use string literals e.g. auto s = "dummy"s;.
Not using using namespace std; cause to failed compile. What is the solution?
operator""s is in 2 inlined namespaces in namespace std. It basically looks like this:
namespace std
{
inline namespace literals
{
inline namespace string_literals
{
//operator""s implementation
//...
}
}
}
So, to only get the string literals, use using namespace std::string_literals;.
Alternatevely, if you want to include every literal - including the string literals (like s for seconds if you include chrono, ...): using namespace std::literals;.
Depending on the situation, you might also consider using:
using std::string_literals::operator""s;
instead of importing every name from that namespace.
Note that you should still not include it in a header, at global level
(but you can do it inside inline or member functions or namespaces you control)
For string literals you can use:
using namespace std::string_literals;
That will pull about 4 names into the namespace which is fine. But when you do:
using namespace std;
Then you pull in thousands of names, many of which are commonly used in programs like count and time. This can create hard to find bugs from accidentally referring to the wrong thing.
That's not an issue with the string literals.
Also none of the names that using namespace std::string_literals; brings in should interfere with user defined names because user defined string literals must begin with _ (according to the standard) which avoids conflicts.
However you should still avoid using namespace std::string_literals; in the global namespace of a header file because you should not impose any feature on a user that they don't request.
Above operators are declared in the namespace std::literals::string_literals, where both literals and string_literals are inline namespaces. Access to these operators can be gained with using namespace std::literals, using namespace std::string_literals, and using namespace std::literals::string_literals
Source : std::literals::string_literals::operator""s
I would add the "using namespace" thing inside my block of code:
auto get_greetings()
{
using namespace std::string_literals;
return "Hello world"s;
}
So, the probability of having operator""s overloaded in some library should be ZERO, because the standard suggests we ordinary people should add a suffix with an underscore.
And, since I am adding this using namespace inside my function, no probability of name clashes will occur outside it.

How can I avoiding typing namespace:: overly often in my code?

I use cocos2dx. When I use classes from it I need to type cocos2d:: very often unless I type using namespace cocos2d;.
How can I avoid having to repeat the namespace all the time?
There are several ways to use stuff from other namespaces without having to repeat the namespace on every instance.
Import the entire namespace: using namespace cocos2d; You can now use all members of that namespace by only their name without the namespace prefix. This pollutes your own namespace with possibly quite a few names (depending on the contents of the imported namespace) which might not be desirable.
Import single names from that namespace: using cocos2d::MyClassName; This only imports the given name. The upside is that your namespace is not polluted. The downside is that you will have to do it for every namespace member you want to import. If you only need a few then this approach is fine.
Create a namespace alias: namespace co = cocos2d; Now you can refer to members of the cocos2d namespace as if they were members of the co namespace.
Create a type alias (since C++11): using CoClass = cocos2d::MyClassName; You can then refer to the aliased member with the identifier you chose. This can be especially helpful when an imported type shadows a type in your own namespace.
Chris's answer is correct and complete, but I would add that it's a better idea to explicitly specify every member's namespace to avoid ambiguity in other files that included your header file.
using namespace cocos2d; will implicitly use that namespace in every file that includes your header. You may put it inside the .cpp file. Same thing goes for using cocos2d::MyClassName; and namespace aliases.
Those will all work, but you shouldn't use them.
See that answer to the question: “using namespace” in c++ headers