tags:

views:

251

answers:

3

I've often found myself wanting a way to undo the effect of a using statement or to include all of a namespace (such as std) but exclude a bit to be replaced (such as cout). For some reason this isn't possible. I am wondering if anyone knows why it was decided not to add this ability to the language? Is there some technical reason? I assume it wasn't just forgotten since it doesn't seem slated for C++0x either.

Just to clarify, I'm not looking for workarounds since Google can show me those. I'm looking for an explanation of why this is impossible, and why it was not considered (as far as I can tell) for inclusion in 0x.

+9  A: 

A using directive brings a name or set of names into a given declarative scope.

You can't "un-using" for the same reason that you can't say

int x = 42;
// and later
[remove name x somehow]

There's no way to unintroduce names from a scope at all in C++, regardless where those names came from.

Given that it would overcomplicate name lookup (since names could be both added and removed from a scope), unless there is a really compelling use case, it's unlikely to be considered as a potential language feature.

James McNellis
Also, you wouldn't use `using` in the first place if you didn't want it to apply to the entire scope. If you only need it in a few places, you can manually prefix the namespace to each occurrence.
casablanca
There is a good technical reason for not allowing you to remove or replace names in a scope: linking. The mangled form of namespace::x can only refer to a single address. However, this does not apply to names that are pulled in to a namespace since they would still be mangled with their original namespace. It wouldn't have to complicate lookup. If something like "using namespace std except (cout, cerr);" were possible (as it is in some other langs) those names would never have been in the current namespace so they wouldn't have to be removed.
mstearn
@mstearn: using directives don't have anything to do with linking at all; they only affect name lookup. They don't actually add things (functions or objects) to a declarative scope, they just allow them to be looked up as if they were in that declarative scope. Regardless, there really isn't a good use case for this, which means there isn't really a chance it would be considered as a potential language feature (though, who knows: somehow `std::error_code` made it into C++0x, and IMO there really isn't a particularly good use case for that, at least not in the way it's implemented).
James McNellis
@james: Right, that is why things like "int x" and "using some::x" are fundamentally different.
mstearn
+1  A: 

Mostly because there are workarounds that are sufficiently simple and straightforward that virtually nothing would be gained by including a "feature" for that specific purpose. Though I'm not sure he ever states it directly, I think you could argue that one of the guidelines in the design of C++ has always been to prefer general mechanisms to special-purpose ones, so using the existing scope system (for example) makes more sense than adding some special way to remove something from a scope after it's been introduced.

Jerry Coffin
+2  A: 

This is because the using directive is not meant to be used for native C++ code. It was intended to help migrate C code to C++. In this context, "un-using" doesn't make sense.

-edit- I should have been more specific. In this particular case, it looks like mstearn is using the using directive to include the std namespace globally. Doing this is generally a bad idea because it results in global namespace pollution, and should only be done in certain circumstances, like transitioning from another language to C++.

There are other situations where utilizing the using directive is fine (within a function, namespace composition). However "un-using" doesn't make sense in these situations either.

aCuria
I'm not really sure what this is supposed to mean. Perhaps you can clarify what you mean that _"using directives_ are not meant to be used...?
James McNellis
@James McNellis Good call (+1)
aCuria
@James McNellis There is no good reason to do "using std , cout" rather than "std::cout" other than existing code that might class with new usage and you might want to wrap in a namespace.
Martin Beckett
@Martin: Right; I kind of figured that's what aCuria was getting at; I just wasn't sure whether he knew of some original rationale for `using` that explicitly said it was for migrating legacy code.
James McNellis
@James - I suspect the rationale for 'using' was to stop people complaining that their beautiful concise C' language had got as verbose as Java (or Cobol) !
Martin Beckett
@James - You should have asked about that specifically! How about a quote from the language's creator himself:"Global using directives are a tool for transition and are otherwise best avoided." - Stroustrup, C++ programming language third ed
aCuria