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().
Related
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.
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.
Some library in C++ doesn't use namespace like stl does. Like ncurses, functions available there can be called without namespace. It has move () function that can be accessed globally. And now, I'm taking ncurses library in my class file which will have move function as it's member function. If i write my class like this:
#include <ncurses.h>
class MyClass {
public:
void move (int x, int y) {
// moving
}
void do_something (int x, int y) {
move (x, y);
// do something
}
}
I don't know which move () function will be called by MyClass. I think the problem will gone if can give ncurses library a namespace, so can use (for example) ncurses::move () not just move (). Is it possible to give it namespace? If not, what will you do if you find to something like this (not changing function name of course)?
In this case, you can fully qualify the call, rather than relying on name lookup which basically finds the "nearest" match, like this:
::move(x, y);
This will look for move at the top level, finding the ncurses, no-namespace, version.
For adding an ncurses namespace, not really. You could try:
namespace ncurses {
#include <ncurses.h>
}
but it's really nasty and almost certainly won't work properly. Another way would be to create a wrapper header that manually adds all the functions you are interested in into a namespace, like:
// wrapped_ncurses.h
#ifndef WRAPPED_NCURSES_H
#define WRAPPED_NCURSES_H
#include <ncurses.h>
namespace ncurses {
using ::move;
}
#endif
And then of course you can take this as far as you like towards creating a C++ wrapper for the entire library (or try to find an existing one).
I don't know which move () function will be called by MyClass.
The member function, since that's in the narrower scope. Unqualified name lookup starts in the local scope and works outwards until it finds a match. So here it will look in the function's block scope; then move out to the class; then find MyClass::move and stop there. It won't consider the global namespace outside the class.
Is it possible to give it namespace?
You can qualify the name as ::move to specify the global namespace.
So I have to use some members of Boost library and some from the std namespace. Right now, I have using boost::asio::ip::tcp; declared and am calling appropriate members with std:: and for example tcp::iostream server(). Is there any reason why I shouldn't add another using, namely using namespace std; and then call all the std things without std:: prefix? Can these two somehow collide or cause malfunction?
Provided that it is usually considered a bad practice to have using directives that import names from the std namespace (especially when at namespace scope and/or in a header file), because it easily leads to name clashes, consider the following program:
namespace A { void foo() { } }
namespace B { void foo() { } }
int main()
{
using namespace A;
using namespace B;
foo();
}
How should the compiler resolve the call to foo()? Well, it won't. It is ambiguous, because both A::foo() and B:foo() can now be referred to as the unqualified foo().
If there are entities with the same name in the std namespace and in the global namespace (or in any other namespace for which you have a using directive), ambiguities due to name clashes are likely to arise.
In your specific case, a using directive such as:
using namespace std;
Will be unlikely to clash with the name tcp introduced by your using declaration (notice, that a using declaration imports just one specific name and is, therefore, preferable).
Yet, it is still considered to be poor programming style and you should not do it, regardless of whether you have some other using directive or using declaration already in place.
Yes, they can. The compiler can't resolve the correct namespace in that case. The solution is to use prefixes (for example std::).
You can also put the using namespace keywords inside a function or other block, so the namespace won't be used outside it:
void foo()
{
using namespace ns;
} // ns won't be used after this
Furthermore, namespace usage can be limited to a header:
namespace ns
{
#include "ns.h"
}
However, limiting the namespace to a header is not recommended because it causes problems in many cases.
The other answers do a good job of explaining how ambiguities can be resolved when you have two or more using namespace directives, but it's worth pointing out that the situation is different if you have using declarations that pull in two or more specific names from within namespaces, like this:
namespace A { void foo() { } }
namespace B { void foo() { } }
int main()
{
using A::foo;
using B::foo;
return 0;
}
The above is always a compile error, even though neither foo is ever used. This is because using declarations, as the name suggests, actually declare a name in their enclosing scope to be an alias to a name in some other namespace. This is in contrast to a using namespace directive, which merely makes names available in their enclosing scope without actually declaring any new names.
If you really want to, it's possible to resolve the above code like this:
using fooa = A::foo;
using foob = B::foo;
But using declarations should usually be avoided anyway, because they have some other semantic surprises which can bite you in unexpected, subtle, and sometimes undetectable ways. The exception is using a base class member within a derived class, which is usually OK, though not often necessary.
Like :
using ::size_t; using ::fpos_t; using ::FILE;
In fact it's a question inspired by the comment under this question:
When is .h not needed to include a header file?
This is called using declaration. There are actually two ways you can use the using keyword. There is a third special form of using declarations used inside class definitions, but i'll focus on the general using declaration here. (see below).
using declaration
using directive
These have two very different effects. A using declaration declares a name to be an alias to another declaration or a set of declarations (if you were to name a set of overloaded functions). The name is declared in the current scope. That is, you can use it inside blocks too
int main() {
using std::swap;
// ...
}
This is quite useful if you use a name very often locally and you don't want to prefix it in all uses, and it's also useful in implementing the swap using argment dependent lookup idiom.
A using directive names a namespace and does not declare any names. Instead it will modify name lookup to find names that aren't really declared where it thinks they are. For unqualified name lookup, it find names declared in the enclosing namespace that encloses both the using directive and the target namespace. All names that are declared in the target namespaces will be found:
int cout;
int main() {
using namespace std;
// cout << 1; ambiguous!
}
Here, cout will be thought as being declared twice in the global namespace, and causes an ambiguity (:: encloses both main and std). In qualified namelookup, it will build the transitive closure of a namespace with all the namespaces named in using directives.
using namespace foo;
int main() {
::c++;
}
c is not only looked up in the global namespace, but also in the namespace foo and in the namespaces that foo has using directives for and so on. If however the global namespace would contain a direct declaration (including a using declaration), that declaration will hide the declarations found indirectly by using directives:
using namespace foo;
int c;
int main() {
::c++; // not ambiguous!
}
Using declarations can appear in many places, including inside class definitions. Its meaning is similar to its meaning otherwhere with an important restriction: It declares a name to be an alias to one or more declarations, but the declarations must be members of a base class. This is very useful for making names visible in a derived class that would otherwise be hidden by the same name declared there
struct base {
void f();
};
struct derived : base {
using base::f; // name "f" declared in derived
void f(int); // overloads the using declaration
};
Now you can call d.f(). If there were no using declaration, then name lookup would only find one declaration of f in derived and stop lookup, not delving into the base class scope:
derived d;
d.f(); // invalid without the using declaration
d.f(0); // valid with or without the using declaration
// explicitly starting lookup in base: valid with or without the using declaration
d.base::f();
It also allows to change the accessibility of base-class members, although you should use that sparingly :)
In practice, i found it useful for making virtual member function re-visible:
struct base {
virtual void f();
virtual void f(int);
};
struct derived : base {
// using base::f; would solve it
virtual void f() { ... }
};
Oops - now d.f(0); is invalid because name lookup only finds the zero parameter f! The using directive would solve it. Notice that if you alias a function declaration that has the same parameter types and constness as an explicit declaration (like f() in this case), then the explicit declaration will still hide the one that the using declaration is an alias for - so both f() functions won't conflict in this case.
An alternative to solve this is using the non-virtual interface idiom
struct base {
void f() { do_f(); }
void f(int) { do_f(0); }
private:
virtual void do_f();
virtual void do_f(int);
};
struct derived : base {
private:
virtual void do_f() { ... }
};
struct derived1 : derived {
private:
virtual void do_f(int) { ... }
};
Now, both d.f(0) and d.f() are valid no matter on what object you call it.
Unfortunately the example you're looking at is obscure.
using ::_Filet;
As others have noted, the using declaration makes a name from the specified namespace available in the current namespace. In that file there appear to be no namespaces opened, so you'd assume the current namespace is the global namespace, and also the :: with nothing before it addresses the global namespace. So here we seem to be moving a name from the global namespace into the global namespace. What's up with that?
The answer is in the use of a macro:
_STD_BEGIN
This is defined as namespace std {. So what the using declarations are doing is making those names appear in the std namespace, where otherwise they would only be in the global namespace.
using <some symbol> pull a symbol from its namespace into the current namespace. Assume the following code:
namespace foo {
// Assume you want to use std::string, you can either do
std::string bar;
// or
using std::string;
string bar;
}
As you can see, you can either qualify the symbol using its namespace (first line of code) or the second way. For symbols you use quite often, pulling them into the namespace tends to make the code a little more readable but if you have a conflict (say, foo contains a string class of its own which is bad practise but might happen), qualifying it with the appropriate namespace will allow you to resolve the conflict.
The namespace :: is a special case as it refers to the global namespace; in this particular case, the functions you're referring to are C functions and C doesn't know about C++ namespaces, so they end up in the global namespace.
Namespaces in C++ are a very powerful mechanism to avoid symbol naming clashes and I'd strongly encourage any C++ programmer to use them.
The 'using' keyword allows you to bring names from a namespace into the current namespace.
If you would like to use a name inside a namespace without bringing them into your current namespace, you would have to use the <namespace name>::<name> format, as in the following:
std::cout << "Hello World";
If cout is brought into the current namespace, then you can use it like below:
cout << "Hello World";
The using keyword can be used the following ways:
As a using directive (using namespace <namespace name>;):
using namespace std;
This brings all names inside the std namespace into the current namespace.
As a using declaration (using <namespace>::<member name>;):
using std::cout;
This brings only the std::cout name into the current namespace.
using makes a name from the specified namespace available in the current namespace.