Hello again!
In this video, we are going to look at inline namespaces. In C++,
you can define one namespace inside another.
So we have a namespace A, and inside that we have another namespace B.
So these are "nested" namespaces. If we have any symbols in here,
so functions, classes, variables and so on.
If we want to use them outside the namespace, we have to put the namespace double colon in front.
So if we are using x in this namespace, we have to put B double colon x, because it is defined in
a namespace B inside this namespace. If we are outside any namespace, then we need to put another A
double colon in front of that.
So, A double colon B to put code on x.
In C++11, we can say that the inner namespace is "inline".
So namespace B is inline to namespace A.
The difference is that any symbols which are defined inside the inline namespace B, will appear
to be defined in A.
So if we want to use anything from B in this namespace, we can just use it.
We do not need to put B double colon.
If we are outside the namespace, then this will appear to be defined in A. So we can just put A double
colon x.
And again, we do not need to put the B double colon.
And, just to prove that is allowed. This is used in the C++ standard library. In C++14, there are literals
for strings
and chrono. If we put "s" after a C-style string, that makes it into a C++ string literal.
If we put "s", "h" or "n" after a number, that makes a seconds, hours or minutes literal. These have
their own namespaces, which are inside the literals namespace, which is inside the std namespace.
The string literals
chrono literals are inline to literals.
So if we put "using namespace std::literals", that will bring in all the symbols from string_literals
and chrono_literals.
The literals namespace in turn, is inline to std.
So if we have "using namespace std", which you should not really do unless you are writing toy
programs, that will bring in everything from literals automatically.
Inline
namespaces are also useful if you are developing applications, if you are working with different versions
of code.
We have been occasionally using the Refrigerator class during this course.
We have two versions, one with basic functionality, and an enhanced one which can connect to the Internet.
So let's say we are writing software for refrigerators.
We have a "product" name space where we write all our code.
Then we have two different namespaces.
The "Version1" namespace is for the basic Refrigerator, and the Version2 namespace is for the
enhanced Refrigerator.
And these are both inside the product namespace.
So we have something like this.
This is the product namespace, and we are writing all our code in it.
We have the Version1 and Version2 namespaces which both have a definition of Refrigerator.
If we make the Version1 namespace inline, then the Version1 definition will appear
to be inside the "product" namespace.
So if we just put Refrigerator without any qualification, this will pick up the basic Refrigerator
definition.
If instead, we have Version2 inline, then this class definition will appear to be in the product
namespace, and we will pick up the enhanced Refrigerator.
So you can use this for working with versions.
What you do is, you put the code for the current version in an inline namespace, inside the product
namespace.
The code for the other versions goes in nested namespaces.
If we use symbols without any scope operators, we automatically get the current version.
If we want to use a different version for some reason, then we need to qualify it with the namespace
for that version. And then, later on,
when a new version is released, we make the namespace for that version inline, and the previous version
is changed to a nested namespace.
And all our code will automatically start using the new version unless it has explicit scope operators,
in which case it will continue using the same version it was using before.
So let's try this out.
Here is the Version1 namespace, for the basic Refrigerator class.
The Version2 has the enhanced Refrigerator which can connect to the internet.
This is all code you have seen before, so it is not really important what it does.
And then our product code.
So we write all our code in the product namespace.
We include the headers for both versions.
At the moment, Version1 is defined as inline.
So if we just use Refrigerator without any namespace qualification, this will pick up the Version1
namespace. The basic Refrigerator.
And there we are.
That is the basic Refrigerator.
If we now change this.
So that Version1 becomes a normal, nested namespace and Version2 becomes inline.
So this is inline in the product.
(Better save that)
So now if we use Refrigerator without any qualification, that is going to pick up the Version2 definition,
and we should see it connecting to the Internet.
And there it is.
And please do not hack into my fridge!
Okay.
So that is it for this video.
I will see you next time.
Until then, keep coding!