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.
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.
You should explicitly specify which OneMoreClass you want:
int main()
{
myCustomizations::OneMoreClass foo;
}
Related
I just noticed this. I don't know why this is the case, if i use one element from a namespace i don't want anything else to be accessible without having to use the namespace. For example here, this code is valid:
namespace Test
{
struct Magic
{
int poof;
};
struct Magic2
{
int poof;
};
int Alakazam(const Magic& m)
{
return m.poof;
}
int Alakazam(const Magic2& m)
{
return m.poof;
}
};
using Magic = Test::Magic;
int main()
{
Alakazam(Magic()); // valid
Alakazam(Test::Magic2()); // valid
Test::Alakazam(Magic()); // what i want to only be valid
Test::Alakazam(Test::Magic2()); // this too
}
Any reasoning behind this? Does the spec state that this has to be true?
As suggested by immbis in the comment, this is defined by the standard:
3.4.2: Argument dependent name lookup
When the postfix-expression in a function call is an unqualified-id, other namespaces not considered during the usual
unqualified lookup may be searched, and in those namespaces,
namespace-scope friend function or function template declarations not
otherwise visible may be found. These modifications to the search
depend on the types of the arguments (and for template template
arguments, the namespace of the template argument).
...
If you want to defeat this mecanism, you have to use nested namespace like this, but it's tricky:
namespace Test
{
struct Magic
{
int poof;
};
struct Magic2
{
int poof;
};
namespace Test2 { // use a nested namespace that will not be searched autoamtically
int Alakazam(const Magic& m)
{
return m.poof;
}
int Alakazam(const Magic2& m)
{
return m.poof;
}
}
using namespace Test2; // but give some access to the enclosing namespace
};
Live Demo : Then, your two first calls will not be valid any longer. However, the last call in your example is still possible: you can't prevent the use of fully qualified names outside of the namespace.
So i have the following functions:
GraSys::CRectangle GraSys::CPlane::boundingBox(std::string type, std::string color)
{
CRectangle myObject = CRectangle(color);
return myObject;
}
Since boundingBox is part of the namespace GraSys and i have to use it in order to declare this function , why i don't need to do this inside the function?, why can i just use? why does it let me compile with out a problem ?
CRectangle myObject = CRectangle(color);
insted of :
GraSys::CRectangle myObject = GraSys::CRectangle(color);
Hope my question is not confusing.
You're implementing a function that is declared in the namespace of GrasSys. When you're in that function, you use the declaring name space.
For clarity, consider:
namespace GraSys {
class CRectangle { ... };
class CPlane {
... boundingBox(...); ...
}
void example(...) { ... };
}
When you implement boundingBox, you will be in the namespace declared during the declaration of the function, which is GraSys. CRectangle is declared within GraSys, so you can use it directly. Similarly, note that you can directly call functions as well, so in the above code, you can directly call example in your boundingBox implementation.
This is called unqualified name lookup. You can read the complete lookup rules in the C++ standard section 3.4.1 or in more human-readable form here.
Here is an example from the standard, which may be better than verbose explanations:
namespace A {
namespace N {
void f();
}
}
void A::N::f() {
i = 5;
// The following scopes are searched for a declaration of i:
// 1) outermost block scope of A::N::f, before the use of i
// 2) scope of namespace N
// 3) scope of namespace A
// 4) global scope, before the definition of A::N::f
}
using namespace is like add the name space to the global name space (i.e the :: name space). if you do it, from now on the compiler will look for each symbol in all the used name spaces.
Only in case there is ambiguity (mean a symbol with the same name declared in 2 used name spaces, you will be have to use the namespace for it.
namespace A{
void f();
void g();
}
namespace B{
void g();
}
using namespace A;
using namespace B;
A::f(); //always work
f(); //work since it is the only symbol named f
A::g();//always work
B::g();//always work
g();// error since g is ambiguous.
I want to check for the existence of a function in a specific namespace using SFINAE. I have found SFINAE to test a free function from another namespace which does the job, but there are some things I don't understand.
Currently I have this working code, straight from the linked question:
// switch to 0 to test the other case
#define ENABLE_FOO_BAR 1
namespace foo {
#if ENABLE_FOO_BAR
int bar();
#endif
}
namespace detail_overload {
template<typename... Args> void bar(Args&&...);
}
namespace detail {
using namespace detail_overload;
using namespace foo;
template<typename T> decltype(bar()) test(T);
template<typename> void test(...);
}
static constexpr bool has_foo_bar = std::is_same<decltype(detail::test<int>(0)), int>::value;
static_assert(has_foo_bar == ENABLE_FOO_BAR, "something went wrong");
(the ENABLE_FOO_BAR macro is just for testing purpose, in my real code I don't have such a macro available otherwise I wouldn't be using SFINAE)
However, as soon as I put detail_overload::bar() in any other namespace (adjusting the using directive as needed), the detection breaks silently and the static_assert kicks in when foo::bar() exists. It only works when the "dummy" bar() overload is directly in the global namespace, or part of the ::detail_overload namespace (note the global :: scope).
// breaks
namespace feature_test {
namespace detail_overload {
template<typename... Args> void bar(Args&&...);
}
namespace detail {
using namespace detail_overload;
using namespace foo;
//...
// breaks
namespace feature_test {
template<typename... Args> void bar(Args&&...);
namespace detail {
using namespace foo;
//...
// breaks
namespace detail {
namespace detail_overload {
template<typename... Args> void bar(Args&&...);
}
using namespace detail_overload;
using namespace foo;
//...
// works
template<typename... Args> void bar(Args&&...);
namespace feature_test {
namespace detail {
using namespace foo;
//...
// works
namespace detail_overload {
template<typename... Args> void bar(Args&&...);
}
namespace feature_test {
namespace detail {
using namespace detail_overload;
using namespace foo;
//...
I realize this is the very same problem as the question I linked to, and as mentioned I already have a working solution, but what is not addressed there is why precisely does this happen?
As a side question, is there any way to achieve correct SFINAE detection without polluting the global namespace with either bar() or a detail_overload namespace? As you can guess from the non-working examples, I'd like to neatly wrap everything in a single feature_test namespace.
I'll change it slightly so the fall-back declaration of bar isn't a template (= shorter code), and don't use SFINAE as this is purely a name lookup issue.
namespace foo {
int bar(int);
}
namespace feature_test {
namespace detail_overload {
void bar(...);
}
namespace detail {
using namespace detail_overload;
using namespace foo;
void test() { bar(0); } // (A)
}
}
In line (A), the compiler needs to find the name bar. How is it looked up? It's not argument-dependent, so it must be unqualified lookup: [basic.lookup.unqual]/2
The declarations from the namespace nominated by a using-directive become visible in a namespace enclosing the using-directive; see 7.3.4. For the purpose of the unqualified name lookup rules described in 3.4.1, the declarations from the namespace nominated by the using-directive are considered members of that enclosing namespace.
Note they become in an enclosing namespace, not the enclosing namespace. The details from [namespace.udir]/2 reveal the issue:
[...] During unqualified name lookup (3.4.1), the names appear as if they were declared in the nearest enclosing namespace which contains both the using-directive and the nominated namespace.
That is, for the name lookup of bar inside test:
namespace foo {
int bar(int);
}
// as if
using foo::bar;
namespace feature_test {
namespace detail_overload {
void bar(...);
}
// as if
using detail_overload::bar;
namespace detail {
// resolved
// using namespace detail_overload;
// using namespace foo;
void test() { bar(0); } // (A)
}
}
Therefore, the name bar found in feature_test hides the name (not) found in the global scope.
Note: Maybe you can hack around this issue with argument-dependent name lookup (and a second SFINAE). If something comes to my mind, I'll add it.
In addition to DyP's answer and following his comment:
If your function bar took any arguments, you could make use of dependent name lookup to make it work (w/o a second overload of bar).
Indeed in my real code bar() does take arguments.
As a side question, is there any way to achieve correct SFINAE detection without polluting the global namespace...
So yes, dependent name lookup works like a charm. For the sake of completeness, and in case it can help others in the future, here's my now perfectly working code:
#define ENABLE_FOO_BAR 1
namespace foo {
#if ENABLE_FOO_BAR
int bar(int);
#endif
}
namespace feature_test {
namespace detail {
using namespace foo;
template<typename T> decltype(bar(std::declval<T>())) test(int);
template<typename> void test(...);
}
static constexpr bool has_foo_bar = std::is_same<decltype(detail::test<int>(0)), int>::value;
static_assert(has_foo_bar == ENABLE_FOO_BAR, "something went wrong");
}
All credit goes to DyP, I don't believe I'd have thought about this by myself.
Consider the following snippet:
void Foo() // 1
{
}
namespace
{
void Foo() // 2
{
}
}
int main()
{
Foo(); // Ambiguous.
::Foo(); // Calls the Foo in the global namespace (Foo #1).
// I'm trying to call the `Foo` that's defined in the anonymous namespace (Foo #2).
}
How can I refer to something inside an anonymous namespace in this case?
You can't. The standard contains the following section (§7.3.1.1, C++03):
An unnamed-namespace-definition behaves as if it were replaced by
namespace unique { /* empty body */ }
using namespace unique;
namespace unique { namespace-body }
where all occurrences of unique in a
translation unit are replaced by the
same identifier and this identifier
differs from all other identifiers in the entire program.
Thus you have no way to refer to that unique name.
You could however technically use something like the following instead:
int i;
namespace helper {
namespace {
int i;
int j;
}
}
using namespace helper;
void f() {
j++; // works
i++; // still ambigous
::i++; // access to global namespace
helper::i++; // access to unnamed namespace
}
While Georg gives standard-complient, correct, right, and respectable answer, I'd like to offer my hacky one - use another namespace within the anonymous namespace:
#include <iostream>
using namespace std;
namespace
{
namespace inner
{
int cout = 42;
}
}
int main()
{
cout << inner::cout << endl;
return 0;
}
The only solution I can think of that doesn't modify the existing namespace arrangement is to delegate main to a function in the anonymous namespace. (main itself is required to be a global function (§3.6.1/1), so it cannot be in an anonymous namespace.)
void Foo() // 1
{
}
namespace
{
void Foo() // 2
{
}
}
namespace { // re-open same anonymous namespace
int do_main()
{
Foo(); // Calls local, anonymous namespace (Foo #2).
::Foo(); // Calls the Foo in the global namespace (Foo #1).
return 0; // return not optional
}
}
int main() {
return do_main();
}
The only real way is to put the code you want to access that namespace within the namespace itself. There's no way to resolve to the unnamed namespace otherwise, since it has no identifier you can give it to solve the ambiguous resolution problem.
If your code is inside the namespace{} block itself, the local name gets priority over the global one, so a Foo() will call the Foo() within your namespace, and a ::Foo() will call the namespace at global scope.
Just rename the local namespace function.
What is a "namespace alias" in C++? How is it used?
A namespace alias is a convenient way of referring to a long namespace name by a different, shorter name.
As an example, say you wanted to use the numeric vectors from Boost's uBLAS without a using namespace directive. Stating the full namespace every time is cumbersome:
boost::numeric::ublas::vector<double> v;
Instead, you can define an alias for boost::numeric::ublas -- say we want to abbreviate this to just ublas:
namespace ublas = boost::numeric::ublas;
ublas::vector<double> v;
Quite simply, the #define won't work.
namespace Mine { class MyClass { public: int i; }; }
namespace His = Mine;
namespace Yours { class Mine: public His::MyClass { void f() { i = 1; } }; }
Compiles fine. Lets you work around namespace/class name collisions.
namespace Nope { class Oops { public: int j; }; }
#define Hmm Nope
namespace Drat { class Nope: public Hmm::Oops { void f () { j = 1; } }; }
On the last line, "Hmm:Oops" is a compile error. The pre-processor changes it to Nope::Oops, but Nope is already a class name.
More on this topic http://channel9.msdn.com/Series/C9-Lectures-Stephan-T-Lavavej-Core-C-/Stephan-T-Lavavej-Core-C-1-of-n
It is all about choosing an alias for a looong namespace name, such as:
namespace SHORT = NamespaceFirst::NameSpaceNested::Meow
Then later, you can typedef
typedef SHORT::mytype
instead of
typedef NamespaceFirst::NameSpaceNested::Meow::mytype
This syntax only works for namespaces, cannot include classes, types after the namespace NAME =
Also note that namespace aliases and using directives are resolved at compile time, not run time. (More specifically, they're both tools used to tell the compiler where else to look when resolving names, if it can't find a particular symbol in the current scope or any of its parent scopes.) For example, neither of these will compile:
namespace A {
int foo;
namespace AA {
int bar;
} // namespace AA
namespace AB {
int bar;
} // namespace AB
} // namespace A
namespace B {
int foo;
namespace BA {
int bar;
} // namespace BA
namespace BB {
int bar;
} // namespace BB
} // namespace B
bool nsChooser1, nsChooser2;
// ...
// This doesn't work.
namespace C = (nsChooser1 ? A : B);
C::foo = 3;
// Neither does this.
// (Nor would it be advisable even if it does work, as compound if-else blocks without braces are easy to inadvertently break.)
if (nsChooser1)
if (nsChooser2)
using namespace A::AA;
else
using namespace A::AB;
else
if (nsChooser2)
using namespace B::BA;
else
using namespace B::BB;
Now, a curious mind may have noticed that constexpr variables are also used at compile time, and wonder whether they can be used in conjunction with either an alias or a directive. To my knowledge, they cannot, although I may be wrong about this. If you need to work with identically-named variables in different namespaces, and choose between them dynamically, you would have to use references or pointers.
// Using the above namespaces...
int& foo = (nsChooser1 ? A::foo : B::foo);
int* bar;
if (nsChooser1) {
if (nsChooser2) {
bar = &A::AA::bar;
} else {
bar = &A::AB::bar;
}
} else {
if (nsChooser2) {
bar = &B::BA::bar;
} else {
bar = &B::BB::bar;
}
}
The usefulness of the above may be limited, but it should serve the purpose.
(My apologies for any typoes I may have missed in the above.)
Namespace is used to prevent name conflicts.
For example:
namespace foo {
class bar {
//define it
};
}
namespace baz {
class bar {
// define it
};
}
You now have two classes name bar, that are completely different and separate thanks to the namespacing.
The "using namespace" you show is so that you don't have to specify the namespace to use classes within that namespace. ie std::string becomes string.
my resource: https://www.quora.com/What-is-namespace-in-C++-1