Using namespaces - c++

I have the below code
#include<iostream>
namespace first{
void test()
{
std::cout<<"This is the first one \n";
}
}
namespace second{
void test()
{
std::cout<<"This is the second one \n ";
}
}
int main()
{
using namespace first;
test();
using namespace second;
test();
return 0;
}
The above code gives me compilation error of calling of overloaded function test.
My doubt why cannot the second using statement using namespace second hides the first namespace?
Next I tried declaring the namespace inside a function body, this may sound strange but i tried to check whether i can do that or not, It also resulted in the compilation error. Which makes me wonder is it only at the global scope that I can declare the namespaces?
My third and last question is, is there any way by which I can only declare the two function with the same signature inside two different namespaces and the define them outside the outside the namespace block? Like below
#include<iostream>
namespace first{
void test();
}
namespace second{
void test();
}
int main()
{
return 0;
}
Again idk whether my question is valid or not.

I assume both of the using statements precede the call of test() (as distinct from one before and one after, as you have presented it) since, otherwise, the code is fine.
Namespaces do not hide each other. using namespace first makes the identifiers (types, variable, function names, etc) in first become candidates for matching in subsequent code.
By preceding the call of test() with
using namespace first;
using namespace second;
the effect is that both first::test() and second::test() become candidates for matching a subsequent unqualified usage of test(). The compiler has no reason to prefer one over the other - they are both equally valid matches - so the compiler rejects the code due to ambiguity over which one to select.
Also, test() is not overloaded in your example. Two distinct functions in different namespaces are declared and defined. Their full names (like first::test() and second::test() are distinct.
To answer your second question, namespaces can be declared within namespaces.
For your third question, defining the functions separately from their declaration, is possible;
namespace first
{
void test();
}
void first::test()
{
std::cout<<"This is the first one \n";
}

The error you get is not because of an overload, but because of ambiguity of test(): The compiler "sees" two definitions, first::test() and second::test(), with no hint which one to use.
using namespace second; adds the identifiers from second:: to the global namespace; it does not hide any that are already global (either defined globally or previously introduced via using namespace). That's just the way it works.
Also, namespaces can be declared either at global scope, or inside other namespaces; they cannot be declared inside function bodies (as you found out).
That being said, "trial and error" (what does a given compiler accept or not) is a bad habit. What you're learning is not "the language", but a specific implementation. The difference will come back to haunt you if your code is one day expected to compile on a different implementation, or run on a different platform.
In order to resolve the ambiguity, you can always use the fully qualified names, first::test() and second::test(), both when defining and when calling the functions.

Related

What is the difference between using namespace A and using A::a and how does it affect the scope?

I have a code snippet:
namespace Work {
void catch_mouse();
}
namespace Tom {
using namespace Work;
void catch_mouse();
}
int main() {
Tom::catch_mouse();
}
The above code works and calls Tom::catch_mouse();
But the same code with using declaration produces an error.
namespace Work {
void catch_mouse();
}
namespace Tom {
using Work::catch_mouse;
void catch_mouse(); // gives an error; conflicting declaration of catch_mouse
}
int main() {
Tom::catch_mouse();
}
As I understand, both using namespace Work and using Work::catch_mouse brings the declaration into scope then why the first one compiles and the second one produces error?
There is a subtle difference. A using directive like
using namespace Work;
means that
From the point of view of unqualified name lookup of any name after a
using-directive and until the end of the scope in which it appears,
every name from namespace-name is visible as if it were declared in
the nearest enclosing namespace which contains both the
using-directive and namespace-name.
This means that, when the compilers searches catch_mouse, it will also find it inside the Work namespace. Specifically, in unqualified name lookup:
For an unqualified name, that is a name that does not appear to the
right of a scope resolution operator ::, name lookup examines the
scopes as described below, until it finds at least one declaration of
any kind, at which time the lookup stops and no further scopes are
examined.
In your first case, the compiler will first find the catch_mouse() explicitly declared inside Tom namespace and then stops the search.
You can convince yourself that this is the case by examining the output of this code:
#include <iostream>
namespace Work {
void catch_mouse() { std::cout << "this is work" << std::endl; }
}
namespace Tom {
using namespace Work;
void catch_mouse() { std::cout << "this is tom" << std::endl; }
}
int main() {
Tom::catch_mouse();
}
See it live on Coliru.
The program prints "this is tom" because the compiler has found the catch_mouse in Tom.
Your second case
using Work::catch_mouse;
is a using declaration, which (emphasis mine)
makes the symbol member-name from the namespace ns-name accessible for
unqualified lookup as if declared in the same class scope, block
scope, or namespace as where this using-declaration appears.
This means that you explicitly tell the compiler to "import" the declaration of the Work::catch_mouse inside the current Tom namespace, as if it were declared here.
But then you have conflicting declaration of catch_mouse: should the compiler consider inside namespace Tom the declaration of Work::catch_mouse or of Tom::catch_mouse?
This would also leads an ambiguity: when you call catch_mouse(), should the compiler pick up the Work or the Tom versions? Unlike the first case, both declarations of catch_mouse are on equal footing now.
This is why the code does not compile.
the reason for this behavior is that using a namespace really lets you use the namespace's members without the explicit ::, but using namespace::member is different! it serves as a declaration and is actually called 'using-declarations'.
therefor the above code actually declares two functions of the same name and type which leads to the conflicting declaration error.
you can read more about it here under 'using-declarations':
https://en.cppreference.com/w/cpp/language/namespace

doubts regarding usage of :: (scope_resolution_operator)

when I was studying a book on C++, I came across this.
if we declare a class,
class student {public:
void func(int v1,int v2)
{
//some code
}
//some members.
};
and use a function with same name out of the class (non-member function) like,
void func(int x,inty)
and If I wish to call this non-member function in the member function of the above declared class, the syntax would be,
//inside the member function...
::func(x,y);
}
correct me if I am wrong.otherwise,
assuming I wrote
using namespace std;
in the beginning of the program, Is the below code equivalent to previous one?
//inside the member function
std::func(x,y);
}
and, does the answer change if I use a different namespace other than std?? ie,
provided I use,
using namespace abc
are the following declarations
abc::func(x,y)
and,
::func(x,y)
absolutely equivalent under any conditions or do they change under specific conditions??
Thank you.
in the beginning of the program, Is the below code equivalent to previous one?
//inside the member function
std::func(x,y);
No it isn't. Because you preform a qualified name lookup. It means you specify exactly in what namespace func is to be defined. std::func, if it exists, still belongs the the std namespace, not the global one.
A using namespace directive only makes identifiers available to unqualified name lookup, where it's up to the compiler to figure it out. This point is quite intricate, I know, but it's the reason namespaces can be considered useful.
The problem kicks in when you collide the names.
Do not do using namespace std;, since it can cause collision problem.
These code are identical:
using namespace std;
sort(params...); // Omitted, this will call std::sort
std::sort(params...);
And even if you are using namespace std, std::sort calls the same functions as long as std::std doesn't exist (and defining it from user side is illegal code).
However, abc::func() is not identical to ::func(). :: in the beginning means root namespace, which is the most outside namespace. There's no ambiguity or implicit filling in this case.
The using namespace directive allows your code to use stuff that is in the specified namespace. You can even have several of them:
using namespace x;
using namespace y;
This means that a function call like func() will call the function whose code resides either in x or in y namespace (or, in fact, in the global namespace).
If your code looks like this
using namespace x;
using namespace y;
void func(int, int) {... code ...}
then the func function goes in the global namespace, not in the x or y namespace. That is, ::func refers to this function, while x::func and y::func don't.
To put your code (class, function, etc) in a namespace, use this code:
namespace x
{
void func(int, int) {... code ...}
class student
{
void func(int, int) {... code ...}
};
}
Then, if you want to call the func that is outside your class, you can use x::func() or ::x::func(), but cannot use ::func().

Why can't I overload a non-class function with a class function?

I have two overloaded functions 'func'. func(int,int) is defined outside class and func(int) is defined inside. How can I call func(int,int) from inside the class's member functions?
#include <iostream>
using namespace std;
int func(int a, int b)
{ return a+b;}
class test
{
int a;
public:
int func(int);
int driver();
};
int test::func(int b)
{ return b;}
int test::driver()
{ return func(10,20);}
int main()
{
test A;
cout<<A.driver(); //ERROR: NO MATCHING FUNCTION TO CALL FUNC(INT,INT)
return 0;
}
return ::func(10,20);
Using :: in front of a name means to look in the global namespace. It will then find the global func, not the func contained in the class.
EDIT:
func in the class isn't overloading the global func per se, but is hiding it. When lookup starts for func when it is called, it finds test::func first, even though ::func is a better match. Changing the name or removing test::func will remove the first match that lookup came across, and it will proceed until it finds the next one, ::func.
As to why it doesn't start in the global namespace, there are many reasons. I can't speak for the people who designed it, but these are all problems that would occur if it were changed.
1: Anybody writing code in a namespace would have to qualify every name with the namespace (std::cout vs cout). Failure to do so could lead to silent bugs where the wrong variables were changed, depending on what existed in the scopes above it.
2: Unqualified lookup would find functions less likely to be related to the code sooner (the function right next to where you called it is far more likely to be related to your code than the one in a different header file two namespaces above you).
3: Functions would have the opposite lookup of variables. I can't specify the scope of a local inside a function (void func() { int i; /*no*/func::i = 0;/*no*/}), so lookup for variables would still have to start in the enclosing scope and work outwards. It would make no sense for the two to work in opposite directions.

What does it mean if a method call starts with two colons?

A coworker routinely writes something like this:
::someObject->someMethod(anAttribute, anotherAttribute);
someObject is a global variable.
Those two colons seem strange to me. The code compiles and runs just fine without them.
The coworker claims that those colons make someObject explicitly global and thus prevent confusion with a possible local someObject. I would think that you would not be able to define someObject locally if it was already defined globally?
Could you shed some light on what those colons mean and whether they are necessary?
Your coworker is right. You can indeed define a local someObject which would hide the global someObject within that scope:
SomeClass* someObject = ...;
// here the global object is visible
someObject->someMethod(anAttribute, anotherAttribute); // calls the global object
void someMethod() {
SomeClass* someObject = ...;
// here the local object hides the global
::someObject->someMethod(anAttribute, anotherAttribute); // calls the global object
someObject->someMethod(anAttribute, anotherAttribute); // calls the local object
}
// here again only the global object is visible
someObject->someMethod(anAttribute, anotherAttribute); // calls the global object
Scopes can be embedded within other scopes recursively, thus you may have a namespace within global scope, a class within a namespace, an inner class within the class, a method within an inner class, a block within the method... etc. And you may have variables/classes/methods/... of identical names in any of these scopes. So identifying what entity a specific name is referring to is not a trivial task in C++. It is known as name lookup.
In brief, whenever the compiler finds a name, it looks up that name starting from the innermost scope. I.e. inside someMethod, the name someObject is matched by the object defined locally. ::someObject overrides this default behaviour and makes the compiler search only within the outermost (global) scope, thus it finds the global object instead ofthe local.
You can indeed define a someObject locally even though there is a global one. The two variables have different scope, so the compiler knows there's a difference between the two, and the double colons let you refer to the global one.
This also applies to classes outside of a namespace; i.e., to refer to a class Foo from the class Bar::Foo, you use ::Foo to tell the compiler you are talking about the one that isn't in a namespace.
Here's an example that shows it working:
#include<stdio.h>
int someInt = 4;
int main() {
int someInt = 5;
printf("%d", someInt+::someInt);
return 0;
}
If you compile and run that piece of code, it will output 9.
The coworker claims that those colons
make someObject explicitly global and
thus prevent confusion with a possible
local someObject.
Yes - it means the function can be, and must only be, matched in the global namespace. It makes it obvious you're dealing with a global, and would prevent accidental matching against something more local (beit function local, an object member, namespace member, in a namespace you're using, a Koenig lookup match etc.).
I would think that you would not be
able to define someObject locally if
it was already defined globally?
It would be a very bad idea to make it an error. Say a team of programmers decides they want to add a variable called "last_error" to their namespace: they shouldn't have to worry if existing functions in the namespace use the same name for a local variable. If you copy a function from one namespace or class to another, you shouldn't have to make error-prone identifier substitutions in the implementation.
Regarding the benefits of ::, consider:
namespace X
{
void fn() {
rip(data, bytes); // MP3 rip this data
}
}
...then fn() needs to be moved quickly into namespace Y...
namespace Y
{
void rip(const char* message, int exit_code); /* for fatal errors */
...
}
...a casual copy-paste into the guts of Y could easily overlook that log won't match the same global function it used to when fn was in namespace X, but - as illustrated - the functionality may differ markedly :-).
You can think of each namespace, class/struct and functions forming a tree, where each level must be uniquely keyed (i.e. no same-named classes in the same namespace), but decendents are always independent of each other and their ancestors. Increasing freedom to vary independently is essential for letting many people work simultaneously on a big problem.
Could you shed some light on what
those colons mean and whether they are
necessary?
In this specific usage, the :: probably isn't strictly necessary. It adds a little protection, but makes it harder to move the variable to a more local scope later - though that's not so important because the compiler will tell you about the places that continue to refer to ::x after x is moved.
Just a minor add on to all other nice points which have come in the response.
Basically :: invokes qualified name lookup in the global namespace. However it is not guaranteed to be problem free especially in the face of indiscriminate using directives.
The code shown illustrates an important property of qualified name lookup. The point here is that namespaces nominated by using directives in the global namspace are searched. However using directives in namespaces that have the name being searched are skipped.
namespace Z{
void f(){cout << 1;}
}
namespace Y{
void f(){cout << 2;}
using namespace Y; // This namespace is not searched since 'f' is found in 'Y'
}
#if 0
namespace Z{
void f(){cout << 3;}
using namespace Y; // This namespace is not searched since 'f' is found in 'Y'
}
using namespace Z;
#endif
using namespace Y;
int main(){
::f(); // Prints 2. There is no ambiguity
}
In the code shown, if lines with the #if directive are enabled, there is an ambiguity in resolving the name 'f'.

Nested functions are not allowed but why nested function prototypes are allowed? [C++]

I was reading the linked question which leads me to ask this question.
Consider the following code
int main()
{
string SomeString();
}
All says, compiler takes this as a function prototype and not as a string object. Now consider the following code.
int main()
{
string Some()
{
return "";
}
}
Compiler said this is invalid as I guess nested function definition is not allowed. If it is not allowed, why nested function prototypes are allowed? It is not giving any advantage rather than making confusion (or am I missing some valid points here?).
I figured out the following is valid.
int main()
{
string SomeFun();
SomeFun();
return 0;
}
string SomeFun()
{
std::cout << "WOW this is unexpected" << std::endl;
}
This is also confusing. I was expecting the function SomeFun() will have a scope only in main. But I was wrong. Why compiler is allowing to compile code like the above? Is there any real time situations where code like the above makes sense?
Any thoughts?
Your prototype is just 'Forward Declaration'. Please check out the Wikipedia article.
Basically, it tells the compiler "don't be alarmed if the label 'SomeFun' is used in this way". But your linker is what's responsible for finding the correct function body.
You can actually declare a bogus prototype, e.g. 'char SomeFun()' and use it all over your main. You will only get an error when your linker tries to find the body of your bogus function. But your compiler will be cool with it.
There are lots of benefits. You have to remember the function body is not always in the same source code file. It can be in a linked library.Also, that linked library may be have a specific 'link signature'.Use conditional defines you may even select the correct link signature at build time using your scoped prototypes.Although most people would use function pointers for that instead.
Hope this helps.
Just as a side note, C++03 does have a roundabout way of defining local functions. It requires abusing the local-class feature:
int main()
{
struct Local
{
static string Some()
{
return "";
}
};
std::cout << Local::Some() << std::endl;
}
This is a convention from C -- like many -- which C++ has adopted.
The ability to declare a function inside another function in C is a decision that most programmers probably consider regrettable and unnecessary. Particularly with modern OOP design where function definitions are comparatively smaller than they are in C.
If you would like to have functions that only exist in the scope of another function, two options are boost::lambda and C++1x lambda.
As to why your declaration of
void f() {
void g(); g();
}
is better than this one
void g();
void f() {
g();
}
It's generally good if you keep declarations as local as possible, so that as few name clashes as possible result. I say it's arguable whether declaring a function locally (this way) is really fortunate, as i think it's still better to ordinary include its header and then go the "usual" way, which is also less confusing to people not knowing about that. Sometimes, it's also useful to work around a shadowed function
void f() {
int g;
// oops, ::g is shadowed. But we can work around that
{
void g(); g();
}
}
Of course, in C++ we could call function g using its_namespace::g() - but in the old days of C, that wouldn't have been possible, and that thing allowed the programmer to still access the function. Also note that while syntactically it is not the same, semantically the following does also declare a function within a local scope, that actually targets a different scope.
int main() {
using std::exit;
exit();
}
As a side note, there are more situations like that where the target scope of a declaration is not the scope where that declaration appears in. In general, the entity you declare becomes a member of the scope in which the declaration appears. But that's not always the case. Consider for example friend declarations, where that thing happens
struct X { friend void f() { std::cout << "WoW"; } };
int main() { void f(); f(); } // works!
Even though the function declaration (and definition!) of f happened within the scope of X, the entity (the function itself) became a member of the enclosing namespace.
Function prototypes are hints for the compiler. They indicate that the functions are implemented somewhere else, if not already discovered. Nothing more.
When you declare a prototype as you are doing you are basically telling the compiler to wait for the linker to resolve it. Depending where you write the prototype the scoping rules apply. There is nothing technically wrong writing the prototype inside your main() function (although IMHO a bit messier), it just means that the function is only locally known inside the main(). If you would have declared the prototype at the top of your source file (or more commonly in a header file), the prototype/function would be known in the whole source.
string foo()
{
string ret = someString(); // Error
return ret;
}
int main(int argc,char**argv)
{
string someString();
string s = somestring(); // OK
...
}