34

With using namespace I make the whole contents of that namespace directly visible without using the namespace qualifier. This can cause problems if using namespace occurs in widely used headers - we can unintendedly make two namespaces with identical classes names visible and the compiler will refuse to compile unless the class name is prepended with the namespace qualifier.

Can I undo using namespace so that the compiler forgets that it saw it previously?

sharptooth
  • 167,383
  • 100
  • 513
  • 979
  • I bet there's a really ugly hack using the pre-processor for this. But I guess you don't want that – Eli Bendersky Jan 28 '10 at 07:28
  • 6
    @Eli: There isn't in Boost, which probably means that there isn't one. – Travis Gockel Jan 28 '10 at 07:34
  • A possible solution to at least shorten what you have to type would be to `#define N namespace::` at the top of a file and `#undef N` at the bottom. Of course this then means you have to be careful to never use `N` anywhere in the file you don't want `namespace::` to be. A `typedef` could potentially be useful as well. – Yay295 Oct 13 '15 at 18:56

7 Answers7

42

No, but you can tell your coworkers that you should never have a using directive or declaration in a header.

rlbond
  • 65,341
  • 56
  • 178
  • 228
  • 4
    Unfortunately, a third party library (https://opencv.org/platforms/cuda.html) requires this and we cannot rewrite it. This does not look like an answer, many things should be avoided in the life but are inevitable. – Audrius Meškauskas Aug 16 '18 at 08:54
  • @AudriusMeškauskas being impractical doesn't make it incorrect. – Mark Ransom Apr 11 '23 at 00:58
16

As others said, you can't and the problem shouldn't be there in the first place.
The next-best thing you can do is bring in your needed symbols so that they are preferred by the name look-up:

namespace A { class C {}; }
namespace B { class C {}; }
using namespace A;
using namespace B;

namespace D {
    using A::C; // fixes ambiguity
    C c;
}

In some cases you can also wrap the offending includes with a namespace:

namespace offender {
#  include "offender.h"
}
Georg Fritzsche
  • 97,545
  • 26
  • 194
  • 236
  • 7
    That last technique can be a can of worms. If offender.h includes headers that are `#define` protected, now those symbols are stuck in offender. You could try to put its entire interface package comprehensively in a new namespace, but still hope it doesn't include system headers. And if it works once, it might break in the next version. – Potatoswatter Jan 28 '10 at 08:02
7

No, C++ Standard doesn't say anything about "undo". The best you are allowed to do is to limit scope of using:

#include <vector>

namespace Ximpl {

using namespace std;    
vector<int> x;

}

vector<int> z; // error. should be std::vector<int>

But unfortunately using namespace Ximpl will bring all names from std namespace as well.

Kirill V. Lyadvinsky
  • 97,037
  • 24
  • 136
  • 212
3

Not to my knowledge... But as a rule I only use "using namespace" in .cpp files.

Warpin
  • 6,971
  • 12
  • 51
  • 77
0

The closest, that I'll try to use in header files is following:

//example.h

#ifndef EXAMPLE_H_
#define EXAMPLE_H_


/**
 * hating c++ for not having "undo" of using namespace xx
 */
#define string std::string
#define map std::map

class Example {
public:
    Example (const char *filename);
    Example (string filename);
    ~Example ();
private:
    map<string,complicated_stuff*> my_complicated_map;

};

#undef string
#undef map

#endif //EXAMPLE_H_

after all, defines are #undef -able. There are 2 problems: 1. it is ugly 2. separate #define and #undef for each name from the corresponding namespace are used

Nuclear
  • 1,316
  • 1
  • 11
  • 17
0

As stated you should not use using namespace sth in header files. When you need functionality from a namespace in your implementation you can leverage scopes like this:

void func() {
    // some code agnostic to your namespace.
    {
        using namespace sth;
        // some code aware of sth.
    }
    // some other code agnostic to your namespace.
}
Mohammad Rahimi
  • 965
  • 5
  • 15
0
  1. The thread is aged, though @rlbond might have separated "namespace declaration" from "using directive", so obviously I had to ponder here.
  2. @Georg Fritzsche encourages toxic environ with naming his "offender". In the least, you found any work product something business-disagreeable.
  3. Personally, I do not like sprinkling "std::" everywhere (it becomes a swarm of mosquitoes), though I agree with @rlbond with avoiding any using namespace clause within any header. Separating execution code away from header files (as: establishing a link library) is always good programming practice.
  • Rather than `using namespace std` just be selective: `using std::vector; using std::string;` and you'll be swatting many fewer mosquitoes. – Mark Ransom Apr 11 '23 at 00:56