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.
Related
Quote from the standard:
A using-directive specifies that the names in the nominated namespace
can be used in the scope in which the using-directive appears after
the using-directive. 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.
Look at this code:
namespace A {
int fn() { return 1; }
}
namespace Inner {
int fn() { return 2; }
namespace B {
using namespace A;
int z = fn();
}
}
Here, before I knew the exact rules of namespaces, I had expected that z will be initialized to 1, as I written using namespace A, so expected that A::fn() will be used. But it is not the case, z will be initialized to 2, as Inner::fn() is called because of the rule I quoted.
What is the rationale behind this behavior: "as if they were declared in the nearest enclosing namespace which contains both the using-directive and the nominated namespace"?
What would be the cons, if using namespace worked as applying using declarations for everything in that namespace?
Note: this is the related issue that motivated me to ask this question.
A desirable property of a namespace system is that of what I call incremental API compatibility. That is, if I add a symbol to a namespace, then any previously working program should keep working and mean the same thing.
Now, plain C++ with overloads is not incrementally API compatible:
int foo(long x) { return 1; }
int main()
{
foo(0);
}
Now I add the overload int foo(int x) { return 2; } and the program silently changes meaning.
Anyway, when C++ people designed the namespace system they wanted that when incrementing an external API, previously working code should not change the namespace from where the symbol is chosen. From your example, the previous working code would be something like:
namespace A {
//no fn here, yet
}
namespace Inner {
int fn() { return 2; }
namespace B {
using namespace A;
int z = fn();
}
}
And z is easily initialized to 2. Now augmenting namespace A with a symbol named fn will not change the meaning of that working code.
The opposite case does not really apply:
namespace A {
int fn() { return 1; }
}
namespace Inner {
// no fn here
namespace B {
using namespace A;
int z = fn();
}
}
Here z is initialized to 1. Of course, if I add fn to Inner it will change the meaning of the program, but Inner is not an external API: actually, when Inner was written initially, A::fn did already exist (it was being called!), so there is no excuse for being unaware of the clash.
A somewhat practical example
Imagine this C++98 program:
#include <iostream>
namespace A {
int move = 0;
void foo()
{
using namespace std;
cout << move << endl;
return 0;
}
}
int main()
{
A::foo();
return 0;
}
Now, if I compile this with C++11, everything works fine thanks to this using rule. If using namespace std worked as applying using declarations for everything in that namespace, then this program would try to print function std::move instead of A::move.
I've been reading through the namespace chapter in The C++ Programming Language by Bjarne Stroustrup and got confused about how functions get called using Argument-Dependent Lookup. The following are code snippets from the book:
Snippet 1
namespace Chrono {
class Date { /* ... */ };
bool operator==(const Date&, const std::string&);
std::string format(const Date&); // make string representation
// ...
}
void f(Chrono::Date d, int i)
{
std::string s = format(d); // Chrono::format()
std::string t = format(i); // error: no format() in scope
}
This snippet makes sense to me since Chrono is a namespace used in the function f's arguments and therefore it is searched successfully for a format(Date) function. It also appears the function f and namespace Chrono share the same scope, which confuses me about the next snippet:
Snippet 2
namespace N {
struct S { int i };
void f(S);
void g(S);
void h(int);
}
struct Base {
void f(N::S);
};
struct D : Base {
void mf();
void g(N::S x)
{
f(x); // call Base::f()
mf(x); // call D::mf()
h(1); // error: no h(int) available
}
};
This makes sense to me up until the line "h(1);" Since both structs and namespace N share the same scope, why can't the function "void h(int)" be found in namespace N?
Stroustrup does go on to say that "If an argument is a member of a namespace, the associated namespaces are the enclosing namespaces." Since the argument to g is a member of namespace N, does this mean the enclosing namespace is the global namespace which does not contain a function "h(int)"? If that's the case, why wouldn't Snippet 1 fail if the enclosing namespace is the global namespace which also doesn't include a "format(Date)" function?
Thanks in advance for insight into this matter!
ADL applies based on the types of the arguments in the call itself, not the types of the parameters of the function the call may or may not be in.
In format(d), format is looked up in Chrono because an argument to that call, d, is of the type Chrono::Date, and Chrono is an associated namespace of that type. Whether the function containing the call is void f(Chrono::Date d, int i) or void f() is irrelevant. (Obviously, in the latter case, assuming that there's a Chrono::Date d;.)
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.
I have a question regarding the standard ADL resolution in C++.
Here is a sample code explaining my enquiry:
#include <string>
// The mechanism:
namespace A {
template< class C >
::std::string scope(const C*)
{ return "A"; }
namespace B {
template< class C >
::std::string scope(const C *foo)
{ return A::scope(foo)+"::B"; }
} // namespace B
} // namespace A
::std::string scope(...)
{ return ""; }
// The test classes
struct foo {};
namespace A {
struct foo {};
namespace B {
struct foo {};
}
}
// The usage
int main()
{
foo *Foo=0;
A::foo *FooA=0;
A::B::foo *FooB=0;
scope(Foo); // OK, returns ""
scope(FooA); // OK, returns "A"
scope(FooB); // On one compiler, OK returns "A::B" ; On another, compiler error "Ambiguous call" between A::scope() and A::B::scope()
}
So, my question is what is the standard regarding ADL?
Should all the functions from parent namespaces of the argument be found, or only the functions available in the (nested) namespace of the argument + the global functions?
This program has been tested on MSVC 2008 (and compiles with SP but not without...)
According to the standard, ADL works (modulo a couple of special rules)
"as if" the function name were preceded by the namespace; in your last
line, lookup should precede as if you'd written A::B::scope. Which
does not look in the surrounding namespaces.
Note that even within namespace A::B, there would be no ambiguity; in
A::B, A::B::scope hides A::scope. Unqualified name lookup stops
in the scope where it first finds the name.
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.