Date: December 20, 2004
Reply to: Dejan D.M. Milosavljevic
office@ddmrm.com
Controlled access to members of namespace
1. The Problem
In some cases it is necessary to limit access to some members of namespace. Reasons can be various.
Example: in some implementations of STL-a class map is derived from class _Rb_tree. Nothing can stop programmer to use that undocumented class.
This proposal gives solution for controlling access to members of namespace.
2. The Proposal
1. Accessing:
As classes namespace will have members labeled as public/protected/private.
The same as with classes it is not allowed to change their type of access to members.
Members labeled as
public
are accessible from everywhere. The same rule of accessibility for members of namespace according to standard are valid for public members of this proposal.
protected
are accessible only for members of namespace in which they declared.
private
are accessible only for members which are declared in the same body where the private member are also declared.
That means they are not accessible for member of the same namespace which declared in other bodies.
Default access is public.
[Example:
namespace N {
int i; // NOTE: public by default
void p(){ cout << k; }
protected:
int j;
private:
int k;
}
namespace N {
void f(){ cout << i; } // OK: i is accessible
void g(){ cout << j; } // OK: j is accessible
void h(){ cout << k; } // ERROR: k is private from another body
protected:
float k; // ERROR: redeclaration of k
}
end example]
2. Unnamed namespace
Members of unnamed namespace can not have members labeled as public/protected/private.
All members of unnamed namespace are public.
[Example:
namespace {
private: // ERROR: labeling in unnamed namespace is not allowed.
int i;
}
end example]

3. using
public members from namespace from using declaration become public/protected/private depending on how is using labeled.
[Example:
namespace N {
int i;
protected:
int k;
}
namespace M {
protected:
using namespace N; // NOTE: Even with this k is not accessible from M
void f(){ cout << k; } //ERROR: unknown indentifier k
}
void g()
{
cout << N::i << endl; // OK: i is public
cout << M::i << endl; // ERROR: i is not public
}
end example]
4. friends
Declarations can be specified as friend.
The ones specified as friend can only access to protected/private members of the body of namespace where they specified as friend.
[Example:
void fr(void);
namespace N { // first body
friend void fr( void );
private:
void f( void ){ }
}
namespace N { // second body
private:
void g( ){ }
}
void fr( void )
{
N::f(); // OK: fr is friend of first body
N::g(); // ERROR: fr is NOT friend of second body
}
end example]
5. Member of nested namespace
Member of nested namespace can access to:
protected member of enclosed namespace(s)
, private member of enclosed namespace(s) which are in the same body where are member of nested namespace are also declared. [Example:
namespace A {
private:
int i;
protected:
int j;
public:
namespace N{
void f( ) { cout << i; } // OK: in the same body
}
}
namespace A{
namespace N {
void g( ) { cout << i;} // ERROR: i is private;
void h( ) { cout << j; } // OK: j is protected;
}
}
end example]
6. The grammar
namespace-body:
namespace-body-declaration-seqopt

namespace-body-declaration-seq:
namespace-body-declaration
namespace-body-declaration-seq namespace-body-declaration

namespace-body-declaration:
declaration opt
access-specifier : namespace-body-declaration

access-specifier:
private
protected
public

Remarks
By design, there are no effects on existing code.