5

Sorry for this silly question, but is there any way to restrict using directives to the current file so that they don't propagate to the files that #include this file?

missingfaktor
  • 90,905
  • 62
  • 285
  • 365

3 Answers3

15

No, there isn't, which is why you should not use using directives in header files, or any other file that you #include.

  • 3
    To extend this a little bit - the preprocessor (which handles `#include` and other `#`-commands) runs before the compiler ever sees the code. The `using` directive and any other standard keywords are processed by the compiler. Thus, as far as the compiler is concerned, the header files aren't actually separate files - they're code that happens to be in every file in which they are `#include`'d, and thus so are any `using` directives you might put in them. – Amber Apr 05 '10 at 08:53
  • 2
    Aah... sad. Thanks for the answer anyway. – missingfaktor Apr 05 '10 at 09:04
  • @Rahul It's not that bad - you can (and should) of course use `using` directives in your .cpp files. –  Apr 05 '10 at 09:07
4

Perhaps wrapping the code to be included inside its own namespace could achieve the behavior
you want, since name spaces have scope affect.

// FILENAME is the file to be included
namespace FILENAME_NS {
   using namespace std;
   namespace INNER_NS {
      [wrapped code]
   }
}
using namespace FILENAME_NS::INNER_NS;

and in some other file

#include <FILENAME>
// std namespace is not visible, only INNER_NS definitions and declarations
...
Nick Dandoulakis
  • 42,588
  • 16
  • 104
  • 136
4

Technically you should be able to import them to some internal namespace, and then make the things declared in that visible in the namespace meant for the user.

#ifndef HEADER_HPP
#define HEADER_HPP

#include <string>

namespace my_detail
{
    using std::string;
    inline string concatenate(const string& a, const string& b) { return a + b; }   
}

namespace my_namespace
{
    using my_detail::concatenate;
}

#endif

#include <iostream>
#include "header.hpp"

using namespace my_namespace;

int main() 
{
    std::  //required
    string a("Hello "), b("world!");
    std::cout << concatenate(a, b) << '\n';
}

Not sure if it is worth the trouble and how well it plays with "argument-dependent lookup".

visitor
  • 8,564
  • 2
  • 26
  • 15