Question

I've been looking for some clarification for the usage of the using-declarations in header files (I was searching around but couldn't quite get the answer I'm looking for). What I my research concluded so far is, using them in the non-global scope is ok, while namespace directives are bad. That I understood (At least I hope so :)).

So in my example I use shared_ptrs, but I need to support older compilers that do not have them in the std:: namespace but in std::tr1:: for example. Since every class using the shared_ptr needs the same shared_ptr defition, I would have to put the correct #include directive and using declaration in each of these header files. So I moved this part into a seperate header file so I have only one single file where I need to make changes. The decision on which shared_ptr to use, is made via a preprocessor directive HAS_SHAREDPOINTER, which is set if the user has a compiler that supports std::shared_ptr.

SharedPtr.h:

#ifndef SHAREDPTR_H_
#define SHAREDPTR_H_

#ifdef HAS_SHAREDPOINTER
#include <memory>
using std::shared_ptr;
#else
#include <tr1/memory>
using std::tr1::shared_ptr;
#endif

#endif /* SHAREDPTR_H_ */

Now in every header file that uses the shared_ptr, I include this header file. For example in

ModelPar.h:

#ifndef MODELPAR_H_
#define MODELPAR_H_

#include <string>
#include <set>

#include "SharedPtr.h"

class ModelPar {
  private:
    std::set<shared_ptr<ModelPar> > connections;
  ...
};

#endif /* MODELPAR_H_ */

Now I think the way I did it is wrong, since the user that includes any of my header file (using the shared_ptrs) also has the corresponding using declaration in his code. And that's the bad thing, as the user is not aware of this... etc. So I put my using declarations in the global scope. Or? I'm kind of stuck and confused on how to do this properly? Thanks in advance!

Was it helpful?

Solution

Ok I found "the" answer myself. I guess that I was not aware that the using declaration in a namespace is still valid in below namespace scopes with the same name. Now Bjarne's words also makes more sense, that one should not pollute the global namespace :). Please correct me though, if I'm still doing something wrong.

SharedPtr.h:

#ifndef SHAREDPTR_H_
#define SHAREDPTR_H_

#ifdef HAS_SHAREDPOINTER
#include <memory>
namespace blub {
using std::shared_ptr;
}
#else
#include <tr1/memory>
namespace blub {
using std::tr1::shared_ptr;
}
#endif

#endif /* SHAREDPTR_H_ */

ModelPar.h:

#ifndef MODELPAR_H_
#define MODELPAR_H_

#include <string>
#include <set>

#include "SharedPtr.h"

namespace blub {

  class ModelPar {
  private:
    std::set<shared_ptr<ModelPar> > connections;
    ...
  };
}

#endif /* MODELPAR_H_ */

OTHER TIPS

I personally do no see any benefit from having 'using' on any header. Ever.

Not only does it make it extremely hard to re-factor since the compiler errors will become useless if you remove a header header include chain. Getting 300+ errors of missed declarations, types undefined, etc; is not exactly my definition of 'funtimes'.

Sure, you can use some preprocessor magic to to get it done regardless of name collisions. But why? If you have namespace collisions there is problem with your approach, bypass that in that way is as good as turning the fire alarm off and claim there is no fire anymore.

As an extra bonus, it also obscure the ancestry of your class a la "Was I using FooClass from the X namespace? Or was it from Y?".

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top