I am having trouble with header files and namespaces. If we define functions in the namespaces then we can use the name of that namespace as identifier.
This is ok but what is really confusing that most of the functions in C++(which are declared in different header files) are in the std namespace.
Now is the namespace inside the header file or header file inside the namespace?
If the namespace is inside each header file then how can you make a function(which is declared and fully implemented in header file) member of that predefined namespace?
A concrete example:
When i try to use string in C++ then i use #include <string> but then i have to use the identifier to call a function(like std ::stoi).
Now when i open the header file string i see that stoi is fully implemented in the header file string. So how is this function a member of std namespace because in string header file i don't see std anywhere nor it is made a member of std namespace explicitly.
My Question can be very basic but i don't find answer anywhere. Simply declaring a function in namespace and then using it is simple but a function which is declared and implemented in header file, how is that function a member of any namespace and how can one namespace have functions from different header files?
It would be enough if someone tells me how stoi is made a member of std. The rest i can do by myself.
Namespaces can be added to. For example, in one file you might have:
namespace myspace {
int f();
}
and in another:
namespace myspace {
void g();
}
now both f anf g are functions in the namespace myspace. You could also provide the definitions of the functions in the above code, if you wished. Or in an implementation file you could do:
namespace myspace {
int f() {
return 42;
}
}
In Visual studio the <string> header has this line:
_STD_BEGIN
it is a macro defined as:
#define _STD_BEGIN namespace std {
So the namespace is specified in the header file. Then way down on line 179 or so we find stoi:
inline int stoi(const string& _Str, size_t *_Idx = nullptr,
and further down still:
_STD_END
which expands to:
}
at the end of the std namespace.
Related
So I was trying to access a method that is defined in another class and has the prototype in the header. I'm pretty positive I defined it but it keeps popping up undefined reference to SafeCracker.
Main.cpp
#include <iostream>
#include "mystuff.h"
using namespace std;
void BigDog(int KibblesCount);
int main()
{
cout << SafeCracker(1);
return 0;
}
mystuff.cpp
#include <iostream>
using namespace std;
string SafeCracker(int SafeID)
{
return "123456";
}
mystuff.h
using namespace std;
#ifndef MYSTUFF_H_INCLUDED
#define MYSTUFF_H_INCLUDED
string SafeCracker(int SafeID);
#endif // MYSTUFF_H_INCLUDED
Here it tells you that you have an undefined reference, so you don't really have a problem with the prototype.
Had you forgotten to include the header file that contains the prototype you would have gotten something like
main.cpp: In function ‘int main()’:
main.cpp:8:13: error: ‘SafeCracker’ was not declared in this scope
cout << SafeCracker(1);
Your undefined reference is a linker error. The most likely cause would be that you did not use mystuff.cpp when compiling
If you're compiling from the command line, you should give both files as parameters.
If you're using an IDE that calls the compiler, make sure that the file is part of the project.
For example in Code::Blocks right-click on the file name and go "add to project" (If I remember correctly)
It is also possible that you made a typo in the function declaration in mystuff.cpp (that doesn't seem to be the case here though)
Now there is one important thing about your code you should take note of:
It is very bad practice to put a using namespace in a header file.
using namespace std; in a .cpp source file is mostly up to you, and that using statement will only apply to that particular file.
But if you put it in a header file that is meant to be included through #include , the using there will be forced upon any code that includes it.
Here is an example:
main.cpp
#include <iostream>
// including mystuff.h to use that awesome SafeCracker()
#include "mystuff.h"
// I need to use an std::map (basically an associative array)
#include <map>
// the map of my game
class map
{
int tiles[10][10];
};
int main()
{
// The std map I need to use
std::map<int, int> mymappedcontainer;
// The map of my game I need to use
map mytiles;
// The reason why I need to include mystuff.h
cout << SafeCracker(1);
return 0;
}
Normally, my class map should not be a problem since the map I included from the standard library is inside the namespace std, so to use it you would need to go std::map.
The problem here is that, since mystuff.h has using namespace std; in it, the symbol map is already used, and that creates a conflict.
You do not now who will use your header files, or if you will use them again a long time from now, and maybe then you will want to use name that is already used in the std namespace.
I advise you to use std:: before things taken from the standard libraries instead (std::string instead of just string for example)
PS: In C++, "class" refers to a class data structure, and the functions you made here are not part of any class. You should say "defined in another file" or "defined in another translation unit" instead
This question already has answers here:
Is using namespace in an anonymous namespace safe?
(2 answers)
Closed 3 months ago.
I want using namespace std; to apply to classes as well as functions without polluting the global namespace, but I'm wondering if it's an ok approach.
namespace
{
using namespace std;
class S
{
public:
S()
{
cout << "ok";
}
friend ostream operator<<(ostream& os, const S& s);
};
}
Any caveats to this?
It will work but keep in mind the following points:
You should limit its use in a source file, not in a header file (in general you should refrain from using unnamed namespaces in headers since they can easily mess around with your symbol definitions, especially if there are inline functions that use something from the anonymous namespace).
It's a bad practice and adding an additional naming hierarchy layer (i.e. the anonymous namespace) just for laziness is as bad as it sounds.
If it's in header file then it's not preferable as this file could be included in multiple source file. If in some source file then its acceptable
Whilst this looked like a great solution, in my experiments it doesn't do as I expected it would. It doesn't limit the scope of the using directive.
Consider this:
#include <string>
namespace {
string s1; // compile error
}
namespace {
string s2; // compile error
}
string s3; // compile error
int main()
{
}
None of those strings compile because they are not properly qualified. This is what we expect.
Then consider this:
#include <string>
namespace {
using namespace std;
string s1; // compiles fine (as expected)
}
namespace {
string t2; // compiles fine (I didn't expect that)
}
string v3; // compiles fine (I didn't expect that either)
int main()
{
}
So placing a using directive within an unnamed namespace appears to be exactly the same as placing it in the global namespace.
EDIT: Actually, placing a symbol in an unnamed namespace makes it local to the translation unit. So this is why it can't work for the intended purpose.
Therefore it has to be a no-no for headers.
An unnamed namespace doesn't contain the effects of a using-directive:
namespace A {int i;}
namespace {
using namespace A;
}
int j=i,k=::i; // OK
Both qualified and unqualified lookup follow the implicit using-directive for the unnamed namespace and then follow the explicit one within it. Wrapping the unnamed namespace inside another namespace limits the unqualified case to other code within that outer namespace, of course:
namespace A {int i;}
namespace B {
namespace {
using namespace A;
}
int j=i; // OK, as above
}
int j=i, // error: i not found
k=B::i; // OK
However, in either case you might as well write the using-directive outside the unnamed namespace (or not write it at all if it would be problematic, perhaps because it would appear in a header file).
Don't take the decision to use an anonymous namespace just so you can limit the scope of a using directive.
That being said, if an anonymous (or any other) namespace is already there and you want the advantages of the using inside it, it's fine as long as your coding standards okay it.
To keep class definition in header file clean, I decided to move implementations of templated functions into another *.h file, which I include in the main header. Now I would like to make use of using namespace there, to make code more readable.
But using namespaces would affect the whole application, since the file gets included in the header which itself gets included in the whole application. The using of the namespaces would spread out of the file.
How can I handle this?
You can put using namespace XX inside function definitions to scope the using declaration to that function:
int func( ...args... )
{
using namespace std;
// ... body of function
}
Use a namespace alias.
namespace submod_ = topspace::other_project::module::submodule;
Then you can use submod_ wherever you would require the very long namespace.
This requires you to still use submod_ where you would have the long namespace qualifier. In that sense, it doesn't exactly answer your question. But I would argue that the explicitness of the qualification aids readability and helps prevent mistakes.
There are real examples of StackOverflow questions where a "using" declaration brought in "lurking" functions which the code author did not realize.
You can place the using namespace in the namespace of your 'main header':
Header.h
#include <string>
namespace Test
{
using namespace std;
string f()
{
return "Test";
};
}
main.cpp
#include "Header.h"
int main()
{
Test::f();
string test; // Error: identifier "string" is undefined
std::string test;
return 0;
}
for using cout, I need to specify both:
#include<iostream>
and
using namespace std;
Where is cout defined? in iostream, correct? So, it is that iostream itself is there in namespace std?
What is the meaning of both the statements with respect to using cout?
I am confused why we need to include them both.
iostream is the name of the file where cout is defined.
On the other hand, std is a namespace, equivalent (in some sense) to java's package.
cout is an instance defined in the iostream file, inside the std namespace.
There could exist another cout instance, in another namespace. So to indicate that you want to use the cout instance from the std namespace, you should write
std::cout, indicating the scope.
std::cout<<"Hello world"<<std::endl;
To avoid the std:: everywhere, you can use the using clause.
cout<<"Hello world"<<endl;
They are two different things. One indicates scope, the other does the actual inclusion of cout.
In response to your comment
Imagine that in iostream two instances named cout exist, in different namespaces
namespace std{
ostream cout;
}
namespace other{
float cout;//instance of another type.
}
After including <iostream>, you'd still need to specify the namespace. The #include statement doesnt say "Hey, use the cout in std::". Thats what using is for, to specify the scope
If your C++ implementation uses C style header files (many do) then there is a file that contains something similar to:
#include ... // bunches of other things included
namespace std {
... // various things
extern istream cin;
extern ostream cout;
extern ostream cerr;
... // various other things
}
std is the namespace that the C++ standard says most of the standard things should reside in. This is to keep from overpopulating the global namespace, which could cause you difficulty in coming up with names for your own classes, variables, and functions which aren't already used as names for standard things.
By saying
using namespace std;
you are telling the compiler that you want it to search in the namespace std in addition to the global namespace when looking up names.
If the compiler sees the source line:
return foo();
somewhere after the using namespace std; line it will look for foo in various different namespaces (similar to scopes) until it finds a foo that meets the requirements of that line. It searches namespaces in a certain order. First it looks in the local scope (which is really an unnamed namespace), then the next most local scope until over and over until outside of a function, then at the enclosing object's named things (methods, in this case), and then at global names (functions, in this case unless you've been silly and overloaded () which I'm ignoring), and then at the std namespace if you've used the using namespace std; line. I may have the last two in the wrong order (std may be searched before global), but you should avoid writing code that depends on that.
cout is logically defined within iostream. By logically, I mean it may actually be in the file iostream or it may be in some file included from iostream. Either way, including iostream is the correct way to get the definition of cout.
All symbols in iostream are in the namespace std. To make use the the cout symbol, you must tell the compiler how to find it (i.e. what namespace). You have a couple of choices:
// explicit
std::cout << std::endl;
// import one symbol into your namespace (other symbols must still be explicit)
using std::cout;
cout << std::endl;
// import the entire namespace
using namespace std;
cout << endl;
// shorten the namespace (not that interesting for standard, but can be useful
// for long namespace names)
namespace s = std;
s::cout << s::endl;
The #include <iostream> references the header file that defines cout. If you're going to use cout, then you will always need the include.
You do not need to using namespace std;. That's simply allows you to use the shorthand cout and endl and the like, rather than std::cout and std::endl where the namespace is explicit. Personally I prefer not to use using namespace ... since it requires me to be explicit in my meaning, though it is admittedly more verbose.
With using namespace I make the whole contents of that namespace directly visible without using the namespace qualifier. This can cause problems if using namespace occurs in widely used headers - we can unintendedly make two namespaces with identical classes names visible and the compiler will refuse to compile unless the class name is prepended with the namespace qualifier.
Can I undo using namespace so that the compiler forgets that it saw it previously?
No, but you can tell your coworkers that you should never have a using directive or declaration in a header.
As others said, you can't and the problem shouldn't be there in the first place.
The next-best thing you can do is bring in your needed symbols so that they are preferred by the name look-up:
namespace A { class C {}; }
namespace B { class C {}; }
using namespace A;
using namespace B;
namespace D {
using A::C; // fixes ambiguity
C c;
}
In some cases you can also wrap the offending includes with a namespace:
namespace offender {
# include "offender.h"
}
No, C++ Standard doesn't say anything about "undo". The best you are allowed to do is to limit scope of using:
#include <vector>
namespace Ximpl {
using namespace std;
vector<int> x;
}
vector<int> z; // error. should be std::vector<int>
But unfortunately using namespace Ximpl will bring all names from std namespace as well.
Not to my knowledge... But as a rule I only use "using namespace" in .cpp files.
The closest, that I'll try to use in header files is following:
//example.h
#ifndef EXAMPLE_H_
#define EXAMPLE_H_
/**
* hating c++ for not having "undo" of using namespace xx
*/
#define string std::string
#define map std::map
class Example {
public:
Example (const char *filename);
Example (string filename);
~Example ();
private:
map<string,complicated_stuff*> my_complicated_map;
};
#undef string
#undef map
#endif //EXAMPLE_H_
after all, defines are #undef -able.
There are 2 problems:
1. it is ugly
2. separate #define and #undef for each name from the corresponding namespace are used
As stated you should not use using namespace sth in header files. When you need functionality from a namespace in your implementation you can leverage scopes like this:
void func() {
// some code agnostic to your namespace.
{
using namespace sth;
// some code aware of sth.
}
// some other code agnostic to your namespace.
}