What is the best/cleanest way to use namespaces in packaged code?
E.g. in libraries like boost there seem to be very organized namespaces management, some techniques are used that allow to disambiguate names. The important thing, however, is that one won't see much code like
typedef namespace1::namespace2::sth_else::a_class<namespace3::namespace4::b_class> type;
usually, there's not much cross-namespacing, which indicates good architecture but also a good namespace management. The question is: what IS the good namespace management?
Say we have file structure like this:
component1/... (depends on reusable_if)
component2/... (depends directly on reusable_if and on component 1)
reusable/
reusable/some_part/
reusable/some_part/...
reusable/some_other_part/
reusable/some_other_part/...
reusable/SthThatUsesBothReusableParts.h (implements reusable_if/ISth.h)
reusable/SthThatUsesBothReusableParts.cpp (implements reusable_if/ISth.h)
reusable_if/
reusable_if/ISth.h (pure abstract class)
reusable_if/ISthElse.h (pure abstract class)
main.cpp (e.g. instantiates SthThatUsesBothReusableParts and passes to component1/2)
The reason why there is reusable_if/ folder is because both component1 and component2 want to reuse the same interfaces (hence none of them 'owns' the interfaces exclusively). Also, the assumption is that the project is indeed very big and needs proper namespaces for classes in each of the folders.
How would you apply namespaces in such a project?
Say I declare all classes in reusable/ in namespace ::reusable
. Should I put interfaces from reusable_if into namespace ::reusable
or into ::reusable_if
? Or maybe into none since it is used by component1 and component2?
What about namespaces in component1 and component2? Anything to remember?
What about keyword using
? Let's say that I decide to add this ::reusable_if
namespace. Can I put using reusable_if
into header files in component1 and component2, provided that using ...
is placed inside namespace ::component1
and ::component2
?
I am open to any suggestions, also those not necessarily related to the above example.
Packages are used in Java in order to prevent naming conflicts, to control access, to make searching/locating and usage of classes, interfaces, enumerations and annotations easier, etc. A namespace is designed for providing a way to keep one set of names separate from another.
Namespace packages allow you to split the sub-packages and modules within a single package across multiple, separate distribution packages (referred to as distributions in this document to avoid ambiguity).
A namespace is a declarative region that provides a scope to the identifiers (the names of types, functions, variables, etc) inside it. Namespaces are used to organize code into logical groups and to prevent name collisions that can occur especially when your code base includes multiple libraries.
The main difference between namespace and package is that namespace is available in C# (. NET) to organize the classes so that it is easier to handle the application, while package is available in Java and groups similar type of classes and interfaces to improve code maintainability.
Personal opinion disclaimer. Your question basically asks for subjective answers, and will probably be closed for it, but I'll give it a shot.
Namespaces are primarily useful to avoid identifier clashes. There is "your" namespace (mylib::
), and the namespaces of everybody else (std::
, boost::
, icu::
, ...), and that is about as far as namespaces should be taken.
There is little benefit to be had by subdividing your project (as in, "your team's project") into sub-namespaces, unless you get a problem with identifier clashes -- in which case you should reconsider your strategy of calling your classes X
and Y
. ;-)
Things are a bit different in huge libs, like Boost. They effectively consist of many different projects, maintained by seperate teams, so there's a problem of project-specific identifiers clashing with each other if they were all lumped into boost::
(and the clash possibly not showing up in casual testing).
If you stop looking at boost::filesystem
as a "sub-namespace", and instead look at boost::
as an "identity wrapper" for the individual projects filesystem::
, thread::
, program_options::
and whatnot, so that they look more "Boost-ish", the picture becomes clearer.
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