Can I undo the effect of "using namespace" in C++?
Asked Answered
N

7

35

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?

Nonesuch answered 28/1, 2010 at 7:23 Comment(3)
I bet there's a really ugly hack using the pre-processor for this. But I guess you don't want thatEpigram
@Eli: There isn't in Boost, which probably means that there isn't one.Martinic
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.Forespent
K
44

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

Knob answered 28/1, 2010 at 7:28 Comment(2)
Unfortunately, a third party library (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.Sheeb
@AudriusMeškauskas being impractical doesn't make it incorrect.Warnke
E
17

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"
}
Estevez answered 28/1, 2010 at 7:33 Comment(1)
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.Kerouac
F
8

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.

Fairish answered 28/1, 2010 at 7:46 Comment(0)
V
3

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

Vedi answered 28/1, 2010 at 7:27 Comment(0)
H
1

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

Hanser answered 13/12, 2013 at 8:35 Comment(0)
T
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.
}
Threadgill answered 6/3, 2022 at 4:41 Comment(0)
L
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.
Lock answered 10/4, 2023 at 23:54 Comment(1)
Rather than using namespace std just be selective: using std::vector; using std::string; and you'll be swatting many fewer mosquitoes.Warnke

© 2022 - 2024 — McMap. All rights reserved.