namespaces

B

beliavsky

If I have a file foo.cpp defining functions f1, f2, f3, etc. and a
corresponding header file foo.h, I can #include foo.h in another source
file and then use those functions. This gives me access to ALL the
functions in foo.cpp. What if I only want to use f1 and f2 and do not
want to "pollute" the namespace with all the functions defined in foo?
I could just copy the function prototypes of f1 and f2 to the source
file calling them, but it better to avoid duplicating code.

Using modules in Python and Fortran 90 one would write
from foo import f1,f2 # Python
use foo, only: f1,f2 ! Fortran
 
V

Victor Bazarov

If I have a file foo.cpp defining functions f1, f2, f3, etc. and a
corresponding header file foo.h, I can #include foo.h in another source
file and then use those functions. This gives me access to ALL the
functions in foo.cpp. What if I only want to use f1 and f2 and do not
want to "pollute" the namespace with all the functions defined in foo?
I could just copy the function prototypes of f1 and f2 to the source
file calling them, but it better to avoid duplicating code.

Using modules in Python and Fortran 90 one would write
from foo import f1,f2 # Python
use foo, only: f1,f2 ! Fortran

There is no corresponding feature in C++. Don't include 'f3' into the
same header. Hell, split the entire header and include every prototype
as its own small header, if namespace pollution is what you worry about.

V
 
?

=?ISO-8859-15?Q?Juli=E1n?= Albo

If I have a file foo.cpp defining functions f1, f2, f3, etc. and a
corresponding header file foo.h, I can #include foo.h in another source
file and then use those functions. This gives me access to ALL the
functions in foo.cpp. What if I only want to use f1 and f2 and do not
want to "pollute" the namespace with all the functions defined in foo?

Put all functions in a namespace, and the global namespace is not polluted
at all. The you can use "using" if you want with the functions you want to
make accesible from the global namespace.
 
C

Cy Edmunds

If I have a file foo.cpp defining functions f1, f2, f3, etc. and a
corresponding header file foo.h, I can #include foo.h in another source
file and then use those functions. This gives me access to ALL the
functions in foo.cpp. What if I only want to use f1 and f2 and do not
want to "pollute" the namespace with all the functions defined in foo?
I could just copy the function prototypes of f1 and f2 to the source
file calling them, but it better to avoid duplicating code.

Using modules in Python and Fortran 90 one would write
from foo import f1,f2 # Python
use foo, only: f1,f2 ! Fortran

You can use nested namespaces:

namespace fred
{
void f1();
void f2();
namespace impl
{
void f3();
} // end of namespace impl
} // end of namespace fred

Now the caller can say

using namespace fred;

and f3 will not enter his global namespace.
 
D

Dave Rahardja

Cy said:
You can use nested namespaces:

namespace fred
{
void f1();
void f2();
namespace impl
{
void f3();
} // end of namespace impl
} // end of namespace fred

I consider this very poor style because it leads to a proliferation of
nested namespaces. A much better solution is to split the declarations
into "public" and "private" header files.

In file fred.h:

namespace fred {
void f1();
void f2();
}

In file fred_impl.h:

namespace fred {
void f3();
}

The user will only include fred.h, and see only fred::f1 and fred::f2.
Remember, namespaces are "open" and can be added to in other compilation
units.
using namespace fred;

I also consider this poor style. In a collaborative programming
environment, the author of namespace fred may be actively adding to his
header file. As he adds new entities to namespace fred, a wholesale
"using namespace" statement will pollute your local namespace with more
and more symbols, potentially introducing Wrong Behavior into your program.

A much better style is:

#include "fred.h"
using fred::f1;
using fred::f2;

With those statements, the author of namespace fred can continue to add
to his header file, but only fred::f1 and fred::f2 will be enter into
your local namespace.

-dr
 
C

Cy Edmunds

Dave Rahardja said:
I consider this very poor style because it leads to a proliferation of
nested namespaces.

Nested namespaces is poor style because it leads to ... nested namespaces?
What?
A much better solution is to split the declarations into "public" and
"private" header files.

In file fred.h:

namespace fred {
void f1();
void f2();
}

In file fred_impl.h:

namespace fred {
void f3();
}

The user will only include fred.h, and see only fred::f1 and fred::f2.

That doesn't work if the declarations in fred.h depend on declarations in
fred_impl.h. Sometimes they won't, but sometimes they will. Look at boost
for many examples of the latter.
Remember, namespaces are "open" and can be added to in other compilation
units.


I also consider this poor style. In a collaborative programming
environment, the author of namespace fred may be actively adding to his
header file. As he adds new entities to namespace fred, a wholesale "using
namespace" statement will pollute your local namespace with more and more
symbols, potentially introducing Wrong Behavior into your program.

I agree. The best example is probably the most used: namespace std. It
introduces a hell of a lot of symbols, some of which may not be knowable
until the next standard is released.

The only reason I brought it up is to answer the OP's original question.
A much better style is:

#include "fred.h"
using fred::f1;
using fred::f2;

With those statements, the author of namespace fred can continue to add to
his header file, but only fred::f1 and fred::f2 will be enter into your
local namespace.

-dr

Even better:

fred::f1();

That way if you change the code so that you don't actually use fred::f1()
anywhere you don't have a declaration at the top saying you DO use it. Plus
it is obvious to the reader where the symbol f1 comes from.
 
D

davidrubin

Cy said:
Dave Rahardja said:
Cy said:
You can use nested namespaces:
[...]
A much better solution is to split the declarations into "public" and
"private" header files.

In file fred.h:

namespace fred {
void f1();
void f2();
}

In file fred_impl.h:

namespace fred {
void f3();
}

The user will only include fred.h, and see only fred::f1 and
fred::f2.

That doesn't work if the declarations in fred.h depend on declarations in
fred_impl.h. Sometimes they won't, but sometimes they will. Look at boost
for many examples of the latter.
Remember, namespaces are "open" and can be added to in other compilation
units.

Because of this weakness in the ability of namespaces to provide
insulation against "namespace pollution," it is useful to scope your
functions within a struct:

// foo_util.h
#ifndef INCLUDED_FOO_UTIL
#define INCLUDED_FOO_UTIL

namespace foo {
struct Util {
// Provide a namespace for utility functions that
// operate on 'foo' components.

static int f1();
static int f2();
static int f3();
static int f4();
// etc
};
} // close namespace foo
#endif

Then, you can call 'foo::Util::f1' and 'foo::Util::f2'. You can add to
the 'foo' namespace, but symbols in the 'foo::Util' namespace cannot
cause conflict.
Even better:

fred::f1();

That way if you change the code so that you don't actually use fred::f1()
anywhere you don't have a declaration at the top saying you DO use it. Plus
it is obvious to the reader where the symbol f1 comes from.

Naturally, you always want to qualify your symbols with their correct
namespace (except in, e.g., foo_util.cpp where the implemntation is
encapsulated in the 'foo' namespace).

/david
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,780
Messages
2,569,611
Members
45,280
Latest member
BGBBrock56

Latest Threads

Top