Search code examples
fileheaderdeclarationusing

using declaration in header files


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!


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_ */