6

I've got a namespace with a ton of symbols I use, but I want to overwrite one of them:

external_library.h

namespace LottaStuff
{
class LotsOfClasses {};
class OneMoreClass {};
};

my_file.h

using namespace LottaStuff;
namespace MyCustomizations
{
class OneMoreClass {};
};
using MyCustomizations::OneMoreClass;

my_file.cpp

int main()
{
    OneMoreClass foo; // error: reference to 'OneMoreClass' is ambiguous
    return 0;
}

How do I get resolve the 'ambiguous' error without resorting to replacing 'using namespace LottaStuff' with a thousand individual "using xxx;" statements?

Edit: Also, say I can't edit my_file.cpp, only my_file.h. So, replacing OneMoreClass with MyCustomizations::OneMoreClass everywhere as suggested below wouldn't be possible.

Kyle
  • 4,487
  • 3
  • 29
  • 45
  • 2
    Here's a tip - DON'T use the "using" keyword but instead refer to classes with their fully qualified names: vector<> -> ::std::vector<> ! – Poni Mar 25 '10 at 19:54
  • C++11 will have a nice feature for versioning namespaces (inline namespace) that will allow the user to get exactly this... then again, you might need to wait more than you want for the feature to be in your compiler (unless you are using gcc >4.4) http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2535.htm – David Rodríguez - dribeas Mar 25 '10 at 23:43
  • See also [How do you properly use namespaces in C++?](https://stackoverflow.com/questions/41590/how-do-you-properly-use-namespaces-in-c) – Vadzim Dec 20 '17 at 11:08

2 Answers2

10

The entire point of namespaces is defeated when you say "using namespace".

So take it out and use namespaces. If you want a using directive, put it within main:

int main()
{
    using myCustomizations::OneMoreClass;

    // OneMoreClass unambiguously refers
    // to the myCustomizations variant
}

Understand what using directives do. What you have is essentially this:

namespace foo
{
    struct baz{};
}

namespace bar
{
    struct baz{};
}

using namespace foo; // take *everything* in foo and make it usable in this scope
using bar::baz; // take baz from bar and make it usable in this scope

int main()
{
    baz x; // no baz in this scope, check global... oh crap!
}

One or the other will work, as well as placing one within the scope for main. If you find a namespace truly tedious to type, make an alias:

namespace ez = manthisisacrappilynamednamespace;

ez::...

But never use using namespace in a header, and probably never in global scope. It's fine in local scopes.

GManNickG
  • 494,350
  • 52
  • 494
  • 543
3

You should explicitly specify which OneMoreClass you want:

int main()
{
    myCustomizations::OneMoreClass foo;
}
R Samuel Klatchko
  • 74,869
  • 16
  • 134
  • 187
  • what if I can't edit my_file.cpp though? edited my question above. – Kyle Mar 25 '10 at 19:48
  • 3
    @Kyle: Then stop using `using namespace`. You can't use that then complain about namespace conflicts. That's like having seat-belts in your car, but you rip them out then complain you're not safe. – GManNickG Mar 25 '10 at 19:49