This seems a little backwards to me but it works:
#include <iostream>
namespace nTest
{
struct cTest {};
void fTest(cTest& x)
{
std::cout << "nTest::fTest(cTest&) called" << std::endl;
}
}
int main(void)
{
nTest::cTest x;
fTest(x); //Weird! fTest is resolved since its parameter belongs to nTest.
return 0;
}
Normally, you would need nTest:: in order to access fTest, but its parameter which belongs to nTest appears to add nTest to the list of possible scopes in which to search for fTest. It seems odd to me that the parameter scope influences the function lookup.
This compiles fine in GCC, but I'm wondering is this usage portable? What is the official definition of this scoping mechanism?
A namespace is a declarative region that provides a scope to the identifiers (the names of types, functions, variables, etc) inside it. Namespaces are used to organize code into logical groups and to prevent name collisions that can occur especially when your code base includes multiple libraries.
You can have the same name defined in two different namespaces, but if that is true, then you can only use one of those namespaces at a time. However, this does not mean you cannot use the two namespace in the same program. You can use them each at different times in the same program.
Namespaces in C++ You only need to prefix the function you wish to call with namespace_name:: -- similar to how you would call a static member function of a class. Another convenience of namespaces is that they allow you to use the same function name, when it makes sense to do so, to perform multiple different actions.
Beginning of C++ only. Global scope or global namespace scope is the outermost namespace scope of a program, in which objects, functions, types and templates can be defined. A name has global namespace scope if the identifier's declaration appears outside of all blocks, namespaces, and classes.
That is ADL (Argument Dependent Lookup) or Koenig Lookup (for the designer of the feature). The purpose of the feature is that in many cases the same namespace will contain types and functions that can be applied to those types, all of which conform the interface. If ADL was not in place, you would have to bring the identifiers into scope with using
declarations or you would have to qualify the calls.
This becomes a nightmare since the language allows for operator overloads. Consider the following example:
namespace n {
struct test {};
test operator+( test, test const & ); // implemented
};
int main() {
n::test a,b;
n::test c = a + b; //without ADL: c = n::operator+( a, b )
}
While it might seem like an awkward situation, consider that n
might be the std
namespace, test
might be ostream
, and operator+
could be operator<<
:
int main( int argc, char** ) {
std::cout << "Hi there, there are " << argc << " arguments" << std::endl;
}
Without ADL, the calls to operator<<
would have to be explicit, and moreover you would have to know which of them is implemented as a free function versus a method. Did you know that std::cout << "Hi"
is calling a free function and std::cout << 5
is calling a member function? Not many people realize it, and seriously, almost no one cares. ADL hides that from you.
It is called Koenig aka Argument dependent lookup http://en.wikipedia.org/wiki/Argument-dependent_name_lookup
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With