It's considered bad practice to employ using namespace in C++ headers. Is it similarly a bad idea to use namespace aliasing in a header, and each implementation file should declare the aliases it wishes to use?
Since headers are the places you tend to use fully specified names (since we don't use namespaces in headers), aliases would be useful but they would still propagate though your source when #included.
What is the best practice here? And what is the scope of a namespace alias?
If you put a namespace alias into your header this alias will become part of your (public) API.
Sometimes this technique is used to do ABI compatible versioning (or at least to make breakage visible) like this:
namespace lib_v1 { ... }
namespace lib_v2 { ... }
namespace lib = lib_v2;
or more commonly:
namespace lib {
namespace v1 {}
namespace v2 {}
using namespace v2;
}
On the other hand if you do it just to save some typing it is probably not such a good idea.
(Still much better than using a using directive)
I do it with unnamed namespaces this way:
#include <whatyouneed>
...
namespace {
typedef ...
using ..
namespace x = ...
// anything you need in header but shouldn't be linked with original name
}
// normal interface
class a: public x::...
Related
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.
I am little confused as to which one is the better way to use using C++ keyword for namespaces. Suppose that the following code is in a header file backtrace.h
#include <memory>
using my_namespace1::component1;
using my_namespace2::component2;
namespace my_application {
namespace platform_logs {
class backtrace_log {
//code that creates instances of my_namespace1::component1 and my_namespace2::component2
};
}
}
OR
#include <memory>
namespace my_application {
namespace platform_logs {
using my_namespace1::component1;
using my_namespace2::component2;
class backtrace_log {
//code that creates instances of my_namespace1::component1 and my_namespace2::component2
};
}
}
which one is better and why ?
You should always pull in symbols from other namespaces in as narrow a scope as possible (to not pollute outer namespaces) and generally, only pull in the specific symbols you need, not just the entire namespace.
In headers (that may get included by many users) you should generally refrain from the practice alltogether and instead prefer to always just use explicit namespace qualifications on types.
In a header file... the following example is evil. Never use using namespace... in the global scope of a header file. It forces a lot of unasked for symbols on the user that can cause very hard to fix problems if they clash with other headers.
#include <memory>
using my_namespace1::component1;
using my_namespace2::component2;
namespace my_application {
namespace platform_logs {
class backtrace_log {
//code that creates instances of my_namespace1::component1 and my_namespace2::component2
};
}
}
On the other hand this next example is fine, but to be used with caution. It only makes sense if you want to include all those symbols in your API. This is often the case with internal project name spaces but less likely with third party namespaces.
I would especially avoid even this with very large namespaces like std::.
#include <memory>
namespace my_application {
namespace platform_logs {
using my_namespace1::component1;
using my_namespace2::component2;
class backtrace_log {
//code that creates instances of my_namespace1::component1 and my_namespace2::component2
};
}
}
In your first example whenever you include
backtrace.h
in another file that file will also use those namesapces. So if by mistake someone wrote "blax" in a file where you included backtrace.h and "blax" also happened to be a class or function in you namespace, e.g.:
my_namespace1::component1::blax
the compiler might take his "blax" to mean "my_namespace1::component1::blax"
By placing the using namespace inside another namespace you simply include all those definitions into that namespace, in the previous example, if you went with version two of the code that collision wouldn't happen since "my_namespace1::component1::blax" would be included as my_application::platform_logs::blax.
Overall most coding guides would encourage you to:
a) Prefer to not ever do "using namespace" or at least use it just to shorten (e.g. using short_namespace = first_namespace::another_namepsace::last_namespace)
b) If you do "using namespace" do so in the source file (i.e .cpp or .c files), since the definitions in those files are not included
c) If you do "using namespace" in headers nest it in another namespace (like in your example) so that it doesn't "leak" into the scope of other file which include your header
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.
In the stlport library, I saw this code:
namespace std { }
namespace __std_alias = std;
1. Are they trying to nullify the standard std namespace in the first line?
2. Why in the world would they use a longer alias name in place of the original name?
You need the namespace "in scope" before you can declare an alias to it. The empty namespace std {} informs the compiler that the namespace exists. Then they can create an alias to it.
There are reasons for creating aliases besides creating a shortcut. For example, you can define a macro to "rename" the namespace -- consider the effect of #define std STLPORT_std. Having a alias allows you to access the original namespace provided that you play the correct ordering games with header files.
No, that just makes sure the namespace's name is available in the current scope. You can open and close namespaces at any point, without affecting the contents of the namespace.
I would guess, so they could easily change their library implementation to be in a namespace other than ::std (by changing __std_alias to alias something else). This would be useful, for example, if you want to test two implementations alongside each other.
It is rather annoying to get a compiler error that there is no such namespace as std... What is the compiler thinking? Of course it exists!
Well yes it does, but as with library features, it has to be declared first. That is what the first line is doing.
With the renaming of __std_alias it allows them to give a new alias to a namespace. You may decide to do this in your own code someday.
Perhaps you want to use shared_ptr in your code but do not want to dedicate your code to using namespace boost or std. So you can create an alias, and "point" it at either boost or std. Same with other features that are in boost libraries that later became standard.
This does not tie you to using this namespace for everything as you can have more than one alias, and you can have more than one pointing to the same real namespace.
Let's say we want to call our smart pointer library sml. We can do
namespace sml = boost; // or std
in one place in the code and #include <boost/shared_ptr.hpp> from that point in the code (same header).
Everywhere else in our code we use sml::shared_ptr. If we ever switch from boost to std, just change the one header, not all your code.
In addition to what D.Shawley said, forward declaring a class that's inside a namespace requires the same syntax:
namespace std
{
template <typename T>
class vector;
}
I'm finding that what I've considered "best practice" for use namespace in c++ is hurting the readability of my code, and making me question how to use them well.
My program consists of a few different modules which are mostly built into libraries that the "main" application uses. Each library uses it's own namespace, and their namespaces are all "inside" a project namespace to help project against name conflicts with 3rd party code. So I end up with class names such as "myproject::logging::Logger" and "myproject::reporting::ReportType" (As made up examples).
So far so good. And in my .cpp files I have no problem. I use "using myproject::logging" at the top for example, and can cleanly refer to my Logging class. In the unlikely event of a conflict between two of my namespaces I can just explicitly say which one I want. This works well.
Header files are different though. It's considered bad practice to put using statements into header files as they will affect unrelated code that may not expect them. So I always fully qualify all the names in .hpp files. That was somewhat ugly but managable up to now so I've put up with it. But now I'm increasing using template code in my libraries which means that there is much more actual code in my .hpp files now. And having to fully qualify every name is making the code practically unreadable due to the length of type names.
I'm starting to feel that the benefits of namespaces and best practice for using them are beginning to be outweighed by the unreadablilty of the code I'm having to write. I'm starting to wonder if I would be better abandoning the use of namespaces to gain the benefit of more readable code and fixing any name conflicts if and when they appear.
An alternative is to use short, single layer namespaces so instead of "myproject::logging::Logger" I would merely have "log::Logger" which would help a lot but make the likelyhood of namespace conflicts much higher, and also have the namespaces convey less useful information.
As I've said, this only really affects code in .hpp files as I'm happily using "using namespace" in my implementation files to make this manageable, but it is becoming a problem as I look at my templated code in .hpp files now and think "eww...." which can't be good :P
Anyone got any practical advice?
Here's what I do.
In <mylibrary.h>:
namespace myproject {
namespace mylibrary
{
namespace impl
{
using namespace otherlibrary;
using namespace boost;
using namespace std;
using namespace whatever::floats::your::boat;
class myclass;
class myotherclass;
};
using impl::myclass;
using impl::myotherclass;
};
};
In the source:
#include <mylibrary.h>
using namespace myproject::mylibrary; //clean!
I have been in this situation before. It is often the case that a lot of template functions/classes in your headers are really "implementation", although by the nature of templates in C++ you are forced to put them in a header file. Thus, I just put everything in some "detail" or "implementation" namespace, where I can comfortably use "using namespace". At the end, I "drop" what people should use to the corresponding place. Like this:
namespace myproject { namespace somemodule {
namespace _implementation {
using namespace myproject::othermodule;
using namespace myproject::yetanothermodule;
template <...>
class some_internal_metafunction{
...
};
template <...>
class stuff_people_should_use_outside {
...
};
} // namespace implementation
using stuff_people_should_use_outside ;
}} // namespace myproject::somemodule
This approach might enlarge a bit the names on your compiler reports, though.
Alternatively, you can give up the modules namespaces. But it might not be a good idea for an extremely large project.
Personally? I'd get rid of the "myproject" part. What is the chance that your library will use the exact same namespace name as another and have a symbol defined with the same name as another?
Also, I would suggest shorter names for namespaces you expect to be used in headers.
My experience have been that it is much more convenient to have one namespace for all your code for the reasons you mentioned in your original post. This namespace protects your identifiers from clashing with identifiers from 3rd-party libraries. Your namespace is your dominion and it is easy to keep it name-conflict-free.
I use the following to get rid of enormous amounts of std:: in header file:
// mylibrary.h
namespace myproject {
namespace mylibrary {
namespace impl {
using namespace std;
namespace stripped_std {
// Here goes normal structure of your program:
// classes, nested namespaces etc.
class myclass;
namespace my_inner_namespace {
...
}
} // namespace stripped_std
} // namespace impl
using namespace impl::stripped_std;
} // namespace mylibrary
} namespace myproject
// Usage in .cpp file
#include <mylibrary.h>
using namespace myproject::mylibrary;
It is similar to what was suggested by n.m., but with a modification:
there is one more auxiliary namespace stripped_std.
The overall effect is that line using namespace myproject::mylibrary; allows you to refer to the inner namespace structure, and at the same time it does not bring namespace std into library user's scope.
It's a pity though that the following syntax
using namespace std {
...
}
is not valid in C++ at the time when this post is written.
If your project isn't very very very huge (I mean, very huge), using only myproject should be sufficent. If you really want to divide your project into parts, you can use more generalized namespaces. For example, if I was building a game engine, I would go for namespaces like MyEngine::Core, MyEngine::Renderer, MyEngine::Input, MyEngine::Sound etc.