Preface
I'm trying to increase my C++ code robustness and, for quite some time, I have been plagued with the issue of namespace pollution.
Because using namespace::std;
is a obvious bad practice, I have always explicitly declared my intentions when using data structures and functions from other namespaces, by using using std::array
declarations inside the namespace where I implement my data structures.
But this can still be a problem. For example, if I have a namespace
called products
and, if I declare all of my products data structures inside the products namespace
, namespace pollution will still occur, due to the increase of using std::XYZ
declarations.
It can easily get to a point where, when using the Eclipse CDT indexer, I will see more standard types, functions and data structures inside my own namespaces, than the data types that I myself have implemented.
My Unsuccessful Solution
In order to achieve some contention, I decided to try the Boost Lib example and isolate the data structures implementation in their own namespace. Boost uses the detail namespace
for this.
But now I have a bigger problem because of the C++ friendship mechanism and how data and functions are declared in namespaces.
The following code uses the c++ friendship mechanism in order to prevent the instantiation of ProductA
by any other object except for the FactoryA
objects. It also follows my attempt to isolate the namespace where ProductA
is declared.
Product A Code
#ifndef PRODUCT_A_GUARD__
#define PRODUCT_A_GUARD__
namespace factories {
class FactoryA;
}
namespace products {
namespace productA_detail {
using std::uint32_t;
using std::size_t;
class ProductA {
friend class factories::FactoryA;
const uint32_t productID;
ProductA(const uint32_t& productID)
: productID{productID}
{}
public:
virtual
~ProductA() {}
};
}
using productA_detail::ProductA;
}
#endif //PRODUCT_A_GUARD__
Factory A Code
#ifndef FACTORY_A_GUARD__
#define FACTORY_A_GUARD__
#include <memory>
#include "productA.hpp"
namespace factories {
namespace FactoryA_detail {
using std::uint32_t;
using std::unique_ptr;
using products::ProductA;
class FactoryA {
uint32_t created_products {0};
public:
FactoryA() {}
unique_ptr<ProductA> Created_ProductA() {
return unique_ptr<ProductA>(new ProductA(created_products++));
}
virtual
~FactoryA() {}
};
}
using FactoryA_detail::FactoryA;
}
#endif //FACTORY_A_GUARD__
Main
#include <memory>
#include "factoryA.hpp"
#include "productA.hpp"
int main (){
using std::unique_ptr;
using factories::FactoryA;
using products::ProductA;
FactoryA factory;
unique_ptr<ProductA> product = factory.Created_ProductA();
return 0;
}
This code will not compile with GCC 6.2
The compiler will complain about FactoryA
being already declared at the factories namespace
In file included from test.cpp:4:0:
factoryA.hpp: At global scope:
factoryA.hpp:29:26: error: ‘FactoryA’ is already declared in this scope
using FactoryA_detail::FactoryA;
Because of this issue, I'm unable to devise a helpful way to prevent a namespace pollution by the constant use of the using std::XYZ
declarations and, still be able to make use of the C++ friendship mechanism to prevent misuse of some of my data structures.
Does anyone know a way to achieve my objective or, if it is possible to be achieved in the first place?