In lesson 2.8 -- Naming collisions and an introduction to namespaces, we introduced the concept of naming collisions
and namespaces
. As a reminder, a naming collision occurs when two identical identifiers are introduced into the same scope, and the compiler can’t disambiguate which one to use. When this happens, compiler or linker will produce an error because they do not have enough information to resolve the ambiguity. As programs become larger, the number of identifiers increases linearly, which in turn causes the probability of a naming collision occurring to increase exponentially.
Let’s revisit an example of a naming collision, and then show how we can resolve it using namespaces. In the following example, foo.cpp
and goo.cpp
are the source files that contain functions that do different things but have the same name and parameters.
foo.cpp:
1 2 3 4 5 |
// This doSomething() adds the value of its parameters int doSomething(int x, int y) { return x + y; } |
goo.cpp:
1 2 3 4 5 |
// This doSomething() subtracts the value of its parameters int doSomething(int x, int y) { return x - y; } |
main.cpp:
1 2 3 4 5 6 7 8 9 |
#include <iostream> int doSomething(int x, int y); // forward declaration for doSomething int main() { std::cout << doSomething(4, 3) << '\n'; // which doSomething will we get? return 0; } |
If this project contains only foo.cpp
or goo.cpp
(but not both), it will compile and run without incident. However, by compiling both into the same program, we have now introduced two different functions with the same name and parameters into the same scope (the global scope), which causes a naming collision. As a result, the linker will issue an error:
goo.cpp:3: multiple definition of `doSomething(int, int)'; foo.cpp:3: first defined here
Note that this error happens at the point of redefinition, so it doesn’t matter whether function doSomething
is ever called.
One way to resolve this would be to rename one of the functions, so the names no longer collide. But this would also require changing the names of all the function calls, which can be a pain, and is subject to error. A better way to avoid collisions is to put your functions into your own namespaces. For this reason the standard library was moved into the std
namespace.
Defining your own namespaces
C++ allows us to define our own namespaces via the namespace
keyword. Namespaces that you create for your own declarations are called user-defined namespaces. Namespaces provided by C++ (such as the global namespace
) or by libraries (such as namespace std
) are not considered user-defined namespaces.
Namespace identifiers are typically non-capitalized.
Here is an example of the files in the prior example rewritten using namespaces:
foo.cpp:
1 2 3 4 5 6 7 8 |
namespace foo // define a namespace named foo { // This doSomething() belongs to namespace foo int doSomething(int x, int y) { return x + y; } } |
goo.cpp:
1 2 3 4 5 6 7 8 |
namespace goo // define a namespace named goo { // This doSomething() belongs to namespace goo int doSomething(int x, int y) { return x - y; } } |
Now doSomething()
inside of foo.cpp
is inside the foo
namespace, and the doSomething()
inside of goo.cpp
is inside the goo
namespace. Let’s see what happens when we recompile our program.
main.cpp:
1 2 3 4 5 6 7 |
int doSomething(int x, int y); // forward declaration for doSomething int main() { std::cout << doSomething(4, 3) << '\n'; // which doSomething will we get? return 0; } |
The answer is that we now get another error!
ConsoleApplication1.obj : error LNK2019: unresolved external symbol "int __cdecl doSomething(int,int)" (?doSomething@@YAHHH@Z) referenced in function _main
In this case, the compiler was satisfied (by our forward declaration), but the linker could not find a definition for doSomething
in the global namespace. This is because both of our versions of doSomething
are no longer in the global namespace!
There are two different ways to tell the compiler which version of doSomething()
to use, via the scope resolution operator
, or via using statements
(which we’ll discuss in a later lesson in this chapter).
For the subsequent examples, we’ll collapse our examples down to a one-file solution for ease of reading.
Accessing a namespace with the scope resolution operator (::)
The best way to tell the compiler to look in a particular namespace for an identifier is to use the scope resolution operator (::). The scope resolution operator tells the compiler that the identifier specified by the right-hand operand should be looked for in the scope of the left-hand operand.
Here is an example of using the scope resolution operator to tell the compiler that we explicitly want to use the version of doSomething()
that lives in the foo
namespace:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
#include <iostream> namespace foo // define a namespace named foo { // This doSomething() belongs to namespace foo int doSomething(int x, int y) { return x + y; } } namespace goo // define a namespace named goo { // This doSomething() belongs to namespace goo int doSomething(int x, int y) { return x - y; } } int main() { std::cout << foo::doSomething(4, 3) << '\n'; // use the doSomething() that exists in namespace foo return 0; } |
This produces the expected result:
7
If we wanted to use the version of doSomething()
that lives in goo
instead:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
#include <iostream> namespace foo // define a namespace named foo { // This doSomething() belongs to namespace foo int doSomething(int x, int y) { return x + y; } } namespace goo // define a namespace named goo { // This doSomething() belongs to namespace goo int doSomething(int x, int y) { return x - y; } } int main() { std::cout << goo::doSomething(4, 3) << '\n'; // use the doSomething() that exists in namespace goo return 0; } |
This produces the result:
1
The scope resolution operator is great because it allows us to explicitly pick which namespace we want to look in, so there’s no potential ambiguity. We can even do the following:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
#include <iostream> namespace foo // define a namespace named foo { // This doSomething() belongs to namespace foo int doSomething(int x, int y) { return x + y; } } namespace goo // define a namespace named goo { // This doSomething() belongs to namespace goo int doSomething(int x, int y) { return x - y; } } int main() { std::cout << foo::doSomething(4, 3) << '\n'; // use the doSomething() that exists in namespace foo std::cout << goo::doSomething(4, 3) << '\n'; // use the doSomething() that exists in namespace goo return 0; } |
This produces the result:
7 1
Scope resolution with no prefix
The scope resolution operator can also be used without any preceding namespace (eg. ::doSomething
). In such a case, the identifier (e.g. doSomething
) is looked for in the global namespace.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
#include <iostream> void print() // this print lives in the global namespace { std::cout << " there\n"; } namespace foo { void print() // this print lives in the foo namespace { std::cout << "Hello"; } } int main() { foo::print(); // call foo::print() ::print(); // call print() in global namespace (same as just calling print() in this case) return 0; } |
So why would you actually want to do this? In most cases, you won’t. But we’ll see examples where this becomes useful in future lessons.
Multiple namespace blocks allowed
It’s legal to declare namespace blocks in multiple locations (either across multiple files, or multiple places within the same file). All declarations within the namespace are considered part of the namespace.
circle.h:
1 2 3 4 5 6 7 8 9 |
#ifndef CIRCLE_H #define CIRCLE_H namespace basicMath { inline constexpr double pi{ 3.14 }; } #endif |
growth.h:
1 2 3 4 5 6 7 8 9 10 |
#ifndef GROWTH_H #define GROWTH_H namespace basicMath { // the constant e is also part of namespace basicMath inline constexpr double e{ 2.7 }; } #endif |
main.cpp:
1 2 3 4 5 6 7 8 9 10 11 12 |
#include "circle.h" // for basicMath::pi #include "growth.h" // for basicMath::e #include <iostream> int main() { std::cout << basicMath::pi << '\n'; std::cout << basicMath::e << '\n'; return 0; } |
This works exactly as you would expect:
3.14 2.7
The standard library makes extensive use of this feature, as each standard library header file contains its declarations inside a namespace std
block contained within that header file. Otherwise the entire standard library would have to be defined in a single header file!
Note that this capability also means you could add your own functionality to the std
namespace. Doing so causes undefined behavior most of the time, because the std
namespace has a special rule, prohibiting extension from user code.
Warning
Do not add custom functionality to the std namespace.
When you separate your code into multiple files, you’ll have to use a namespace in the header and source file.
add.h
1 2 3 4 5 6 7 8 9 10 |
#ifndef ADD_H #define ADD_H namespace basicMath { // function add() is part of namespace basicMath int add(int x, int y); } #endif |
add.cpp
1 2 3 4 5 6 7 8 9 10 |
#include "add.h" namespace basicMath { // define the function add() int add(int x, int y) { return x + y; } } |
main.cpp
1 2 3 4 5 6 7 8 9 10 |
#include "add.h" // for basicMath::add() #include <iostream> int main() { std::cout << basicMath::add(4, 3) << '\n'; return 0; } |
If the namespace is omitted in the source file, the linker won’t find a definition of basicMath::add
, because the source file only defines add
(global namespace). If the namespace is omitted in the header file, “main.cpp” won’t be able to use basicMath::add
, because it only sees a declaration for add
(global namespace).
Nested namespaces
Namespaces can be nested inside other namespaces. For example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
#include <iostream> namespace foo { namespace goo // goo is a namespace inside the foo namespace { int add(int x, int y) { return x + y; } } } int main() { std::cout << foo::goo::add(1, 2) << '\n'; return 0; } |
Note that because namespace goo
is inside of namespace foo
, we access add
as foo::goo::add
.
Since C++17, nested namespaces can also be declared this way:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
#include <iostream> namespace foo::goo // goo is a namespace inside the foo namespace (C++17 style) { int add(int x, int y) { return x + y; } } int main() { std::cout << foo::goo::add(1, 2) << '\n'; return 0; } |
Namespace aliases
Because typing the fully qualified name of a variable or function inside a nested namespace can be painful, C++ allows you to create namespace aliases, which allow us to temporarily shorten a long sequence of namespaces into something shorter:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
#include <iostream> namespace foo::goo { int add(int x, int y) { return x + y; } } int main() { namespace boo = foo::goo; // boo now refers to foo::goo std::cout << boo::add(1, 2) << '\n'; // This is really foo::goo::add() return 0; } // The boo alias ends here |
One nice advantage of namespace aliases: If you ever want to move the functionality within foo::goo
to a different place, you can just update the boo
alias to reflect the new destination, rather than having to find/replace every instance of foo::goo
.
It’s worth noting that namespaces in C++ were not originally designed as a way to implement an information hierarchy -- they were designed primarily as a mechanism for preventing naming collisions. As evidence of this, note that the entirety of the standard library lives under the singular namespace std::
(with some nested namespaces used for newer library features). Some newer languages (such as C#) differ from C++ in this regard.
In general, you should avoid deeply nested namespaces.
When you should use namespaces
In applications, namespaces can be used to separate application-specific code from code that might be reusable later (e.g. math functions). For example, physical and math functions could go into one namespace (e.g. math::
). Language and localization functions in another (e.g. lang::
).
When you write a library or code that you want to distribute to others, always place your code inside a namespace. The code your library is used in may not follow best practices -- in such a case, if your library’s declarations aren’t in a namespace, there’s an elevated chance for naming conflicts to occur. As an additional advantage, placing library code inside a namespace also allows the user to see the contents of your library by using their editor’s auto-complete and suggestion feature.
![]() |
![]() |
![]() |
Hi Alex,
and only one function can be written in one namespace? I am asking this "silly" seeming question because do I have to call(?) every function separately or is there another way around?
Hi Ali!
> only one function can be written in one namespace?
No, take the std namespace for example, it has lots of functions (cin, getline, min, max, …)
> do I have to call(?) every function separately or is there another way around?
A namespace is just a helper to organize your code, it does not add such functionality.
WDY mean by >it does not add such functionality. ?
A namespace doesn't automatically add any functions to your code.
But that wasnt quite the question :) or did I ask it wrong? please excuse me for my bad english.
I'm not clear on what you were trying to ask either. Maybe try rephrasing the question?
do I have to call every function separately (one at a time) or is there another way around?
You have to call every function separately.
"However, by including them in the same program, we have now introduced two different functions with the same name and parameters into the same scope (the global scope), which causes a naming collision."
If two functions have the same name, but different parameters, for example:
will this also cause a naming collision?
Hi Maxixxx!
A collision will only occur of the name and parameter types are the same.
Nascardriver's answer is correct. When the function's name is the same but the parameters are different, this is called a function overload. We discuss this in detail in lesson 7.6.
Can the namespace name be anything you want it to be. For example: you named foo "Foo". Or is it just better practice to name it the same name as the file you're currently in.
Hi Daniel!
> Can the namespace name be anything you want it to be
Yes.
> name it the same name as the file you’re currently in
If you're not planning on having more files then this could be a good idea, however, when you're writing bigger projects you're not going to want all your code in one file. Find a name that sums up the contents of the namespace in one word.
Please clear my doubts.
1. Can we have many namespaces under one header?
2. Can we have many functions under one namespace?
Thanks.
Hi ASP!
1. Yes, this will get messy though.
2. Yes. Take the std namespace for example, it has lots of functions (cin, getline, min, max, ...)
Hi Alex,
I have made assumption that anything defined in the standard library lives in the std namespace , which I found later wasn't quite correct..why ?
look at this snippet
iostream and math.h are both part of the std library why cout and endl needed to be defined by std:: but pow() doesn't need and it was in the global namespace ?
pow() isn't part of the c++ standard library. It's part of the C library that C++ inherits. I should probably make it more clear that there's an entire set of functionality inherited from C.
Note that you should be able to access pow() through the standard library as well by including the <cmath> header and using std::pow().
thanks for your tutorial, i have a question, could i put a namespace with a function inside as a function prototype, like this
#ifndef 1
#ifdefine 1
namespace a
{
int add(int x,int y);
}
#endif 1
or i misunderstand something,sorry for my bad English
Yes. Next time you have a question like this, just try it. :)
Hi Alex I love your tutorial easy to understand and your tutorial is the best I found.I just wonder how it takes to master C++.
Why don't you write your own book.You know some people prefer printed book.
Shouldn't there be a semi-colon after namespace foo and namespace goo ?
No.
Which one is better- #include "XYZ.h" or #include <XYZ.cpp>
1) #include "XYZ.h" if XYZ.h is your own header
2) #include if XYZ is a system header
3) Never include a .cpp file.
Why shouldn't a .cpp file be included?
.cpp files are intended to be compiled, not included, as they typically include things (such as functions) that are only allowed to be defined once. If you include a .cpp file into another .cpp file, you're vastly increasing your odds of running into a duplicate definition issue.
Thank you very much. This website is really wonderful. I've also recommended it to my friends. They too love it.
Thanks to you and all your friends for visiting!
Based on the previous sections, variables declared in a block have local scope. So if we declare a variable someVar in a namespace block, say someNamespace, someVar is only accessed from with in the block. But when we use the identifier someNamespace::someVar to refer to this variable from outside of someNamespace block, we are effectively accessing someVar, contradicting the concept of 'local variable'.
Is there a better way to interpret/explain this? So far I try to see the entire namespace block as a special function which 'sells' data local to itself, but how does it differ from other types of blocks(e.g. function definition) on the backend/compiler(tbh I don't really know what it is) level?
Great site btw. Plenty of examples and good tips for programming in general.
I think I see where your confusion is coming from.
Both namespaces and function braces provide scoping for the identifiers declared inside, from the point of declaration to the closing brace (for namespaces, also to other identically named namespaces that follow).
With block scope, identifiers declared inside the block are always local to that block. You're not allowed to access the contents of the block from outside the block (there's no way to even reference the block, and the variables don't exist when the block isn't being executed). In this sense, the contents of a block are private.
On the other hand, with namespaces, identifiers declared inside the namespace are always global. This makes sense: global identifiers are defined in the global namespace. User-defined namespaces are defined inside the global namespace, making them globally accessible as well. The namespace doesn't restrict access to the contents of the namespace -- rather, it just changes how those identifiers need to be qualified to be referenced.
Make sense?
In the last paragraph in the part of "and there’s few good reasons to nest them more than 2 levels deep." you should use 're instead of 's right???
Maybe I am wrong with this typo but well my first language is Spanish after all
Thanks Alex for this amazing tutorial once more.
I've updated the lesson to use "there are", as is correct. Thanks for pointing out the mistake!
No problem. :)
Hello, Alex!
I am wondering why you show here and other places that you put function definitions in header files.
Is it for sake of simplicity? Or am I just mistaking and it is actually legal to do so?
Thank you for any response.
When I do this, it's generally for the sake of simplicity. Although it is legal to do so, it's likely to lead to problems in non-trivial cases.
Hi Alex,
I have a question about a certain sentence of yours. You mentioned, back in the beginning, that "As programs get larger and larger, the number of identifiers increases linearly, which in turn causes the probability of naming collisions to increase exponentially."
I've taken some discrete math, and I'm wondering how exactly this calculation is performed, if you know?
The way I figure, any name can collide with any other name. So if you have N non-colliding names, and you add one more, your odds of collision just increased by N. So I think the formula for number of possible collisions with N identifiers would be N(N-1)/2, which is exponential.
That makes sense. Thank you very much!
tut.cpp
tut.h
constants.cpp
tut.h and constants.cpp are in the same project (tutorial.cbp) !
When i call add() from namespace math from main() in tut.cpp, it gives a linker error...Why?
Edit: I misdiagnosed the problem, so removing my original comment so as not to cause confusion. The author's solution to the issue is in a sub-comment below.
Btw U didnt see properly, i have given a fwd. declaration of function add() in tut.h. But, thanks btw. I fixed it !
May i know How u fixed it?
The mistake that I did was actually i didn't place "constants.cpp" in the same project as "tut.cpp" due to which only the fwd declaration of the function was included and the function was never defined.....
I know it was a very foolish mistake !
You must have gotten me :)
Gotcha man!
Thought it was similar problem but it was other silly one.
Anyway thanks....
Your Welcome ;)
@ Alex,
I respectfully disagree with your explanation. His header file rightfully had a function prototype/forward declaration for add(int,int) and its corresponding definition is in the .cpp file.
My thought is that the reason for the linker error was because the names of the .h and .cpp files do not match! i.e. he used tut.h and constants.cpp. Is it not a requirement for the names to match (i.e. the same) to prevent a linker error??
Great job on the site! Keep it up.
You're partly correct: I misdiagnosed the problem. The author indicated that he forgot to include constants.cpp in his project, so it didn't get compiled.
However, it's also worth noting that C++ doesn't care are all what the name of the files are.
@ Alex,
You wrote: "However, it’s also worth noting that C++ doesn’t care are all what the name of the files are."
Let's say the "namespace math" requirement were dropped (i.e. assume that the forward declaration and the function definition for "int add" do not exist in the math namespace), would the quote above from your comment still hold? In other words, there would be no linker error as long as all the files are included in the same project?
If the answer to the above is YES, is it correct to say that what prevents a linker error is the mere presence of a corresponding function definition for a particular forward declaration, irrespective of where that function definition is?
And if the answer to the above is also YES, so whether there is a correlation in the .h file name and the .cpp file name is a programmer's choice, just for convenience?
> In other words, there would be no linker error as long as all the files are included in the same project?
Yes.
> is it correct to say that what prevents a linker error is the mere presence of a corresponding function definition for a particular forward declaration, irrespective of where that function definition is?
Yes. Forward declarations tell the compiler that the function definition exists somewhere, but not where. The linker connects the function call to wherever the actual function definition is (possibly in a different file altogether).
> whether there is a correlation in the .h file name and the .cpp file name is a programmer’s choice, just for convenience?
Yes, the correlated names is just a best practice to help the programmer keep track of which set of declarations go with which set of definitions.
main.cpp #includes tut.h, which has a definition for function add(), so that definition gets copied into main.cpp and compiled. constant.cpp has it's own definition for add(). So now you have two definitions for the same function, and because functions have external linkage, the collide (have a naming collision) when you try to call them.
Hi Alex,
This tutorial also uses cout rather than std::cout a few times.
Fixed. Thanks for pointing this out.
Hi Alex,
I have a question about Global namespace in the first example. Please let me know if each file (foo.h, goo.h, main.cpp) had its own Global namespace?
You wrote "when main() #included both foo.h and goo.h, both versions of doSomething() were included into the global namespace, which is why the naming collision resulted." I am assuming that both versions of doSomething() were included into the global namespace of main.cpp?
Thanks, Have a great day.
There is only one global namespace. However, this in and of itself isn't sufficient for a collision to occur. For a collision to occur, two names must be introduced into the same scope AND the compiler must not be able to disambiguate them. So long as the names are kept in separate scopes (e.g. in different files with internal linkage), or if the compiler can disambiguate them via some other means (e.g. function overloading), then they won't collide even if they share a name.
Hi Alex,
I have a question about the example in "Multiple namespace blocks with the same name allowed". What would happen if I try to change all the function names (add in add.h, subtract in subtract.hh, and add/subtract in main.cpp) to the same name (for example: doSomething) ?.
Thanks, Have a great day.
You'd get a compile error telling you that you doSomething() was being defined more than once.
No questions, I just wanted to complement you on the quality of this site. Great job. :)
This course is awesome! Thank you whoever created this class! Much obliged. **tips hat**
Hi Alex,
Thanks a lot for the replay. I got now, the link you shared is more informative and I read some other topics as well. this is very nice experience for me.
Whenever I get any doubt, I always remember your name. This site helped me a lot. I completed your tutorials up to templets and error handling. this is simply awesome
Now am trying to understand the way of using all this knowledge in real project by using some open source project like stockfish_chess engine
Once again thanks a lot.
Hi Alex,
Please find the code snippet
surprising thing for me is here no name for the namespace, then how it useful?
Can you please tell me what it means and use of this
the code is something like this
Thanks in advance
I don't understand the question.
Hi Alex,
In the above snippet, a namespace region is created without any specified name to the namespace, Like
How can we access the variable inside this namespace, need to use any namespace resolution(::) for this area
Or it just like a plain area and can access without specifying any namespace resolution.
if it is a plain area, then why it used like this (I saw this type of coding in stockFish open source project for chess engine)
I hope you can understand my explanation,
Oh, yes, I see. You're asking about unnamed namespaces.
According to the C++ spec, an unnamed namespace behaves as if it were replaced by:
In essence, everything inside the unnamed namespace is placed into the global scope, but is only accessible in that particular translation unit/file.
This is essentially a much-less-used but superior method to using the static keyword to make your variables and functions have internal linkage.
See this FAQ answer for more information about this.
I visited the mobile version of this website.
This site looks way more advanced and neat on a mobile phone.
Why isn't the desktop version of this site changed to that kind of interface?
Should namespace functions be declared AND defined within the namespace, or is it more proper to define the function outside of the namespace block using the scope resolution operator? Or, should they be defined within a seperate block with the same namespace name?
Also, with my limited comprehension so far, it seems to make sense that namespaces should only be declared within header files, and every header file should be namespaced. That is to say, everything in the header file(except for the header gaurd), should be within a namespace(probably named after the header file). But I'm sure this is not the case, because I feel like I'm nowhere near seeing the bigger picture yet.
When dealing with namespaces, you'll most commonly see functions declared inside a namespace block in the header, and defined inside a namespace block in the corresponding .cpp file. Trivial functions (e.g. one liners) may be defined in the header (inside the namespace).
Best practice is to put all of your code into namespaces. But realistically, many developers I've met and much of the code I've seen don't follow this practice (with the exception of library code, which generally does).
Hi Alex,
1> I am confused a bit with "using". Is it a "keyword" or a "directive"? I expected it to be a keyword. Becoz I remember reading in the "preprocessor" lesson, you mentioned, Directive are specific instructions that start with # symbol and end with new line (no semi-colon). The preprocessor will scan through the code and look for these directives. "using" doesn't have a # sign, so why is it directive if it is? or am I missing something here???.
2> And, if I understanding everything properly from previous lessons, it isn't a good practice to define your function in a header file, which should typically contain forward declarations, where as definitions in a cpp source file. And to prevent these function forward declarations or variable forward declarations inside a header file from having naming collisions (as all of these by default end up in the global namespace) we limit their scope using keyword "namespace" and defining specific areas for them. Say "namespace functions" and "namespace variables" .
If that's the case, in this tutorial when you explained "namespace", in a headerfile you have defined functions under a namespace foo. Was it done intentionally for simplicity?? is the prior concept of headerfile holding just forward declaration being a good practice and recommended, still true??
or am I making a mistake by considering it as a "carved in stone" rule of good programming.
1) Using is a keyword. In the preprocessor lesson, we talked about preprocessor directives, which start with #. However, there are other kinds of (non-preprocessor) directives as well, such as using directives.
2) Simplicity. Generally you should try to keep function definitions out of your headers and instead use them to propagate forward declarations.
So non pre-processor directives like 'using' are specific instructions for the compiler then??
Yes. In this case, the using directive helps tell the compiler how to resolve identifiers.
Alex,
If main.cpp is in a different file and you include foo.h in main.cpp, would you need to include foo.cpp also in main.cpp?
There may not be a foo.cpp (header files don't have to have a corresponding .cpp file). However, if there is a foo.cpp, you should not #include it from main.cpp (you should only #include headers, not code files). Instead, you should add foo.cpp to your project so your compiler compiles it as a separate file.
Thank you for the swift response Alex!
Although, FAQ isn't a bad idea and hopefully many will read it too. But the truth is, it is more interactive and learning this way (I mean asking questions here and reading through replies). :)
Regarding first example that included foo.h and goo.h, when does the header guards' comes into play? The purpose of the header guard was to prevent the same thing from including twice?
Header guards only prevent the same header from being included more than once into a given file. They do not prevent different headers from being included (once each). In the foo and goo case, header guards wouldn't help since they are different headers.
This question and answer about header guards pop up A LOT in these comments. You could have a FAQ page to which to bat these questions.
Yeah, right? I think this is the most common misunderstanding in C++ for new programmers. A FAQ isn't a bad idea -- but I suspect most readers won't read it before just asking the question anyway. Such is human nature, it seems. :)
Quesiton :
"The using directive tells the compiler that if it can not find the definition for an identifier, it should look in a particular namespace to see if it exists there. "
what if i wanted to use doSomething from Foo ... then typed "using namespace Foo;" but the compiler DID find namespace Goo and it has doSomething as well and since the description above says "if it can not find the definition for an identifier" will it end up using Goo::doSomething instead of what i stated as using ?
The compiler wouldn't know to look in namespace goo unless you told it somehow (either via the goo:: prefix) or a using directive or declaration.
I'm not sure if I'm answering your question, but consider the following program:
well like ...
// someotherfile.cpp or someotherfile.h
namespace foo
{
int doSomething()
{
return 5;
}
}
// main.cpp
int doSomething()
{
return 2;
}
int main()
{
using namespace foo; // tell compiler we want to use doSomething from namespace foo
doSomething(); // compiler DOES find a function doSomething in main.cpp
return 0;
}
so given that it will only look for an identifier in a particular namespace IF it cant find it here (in this case it did find it) is it going to use the one from foo or the one in main.cpp ?
It will give you an ambiguous call since it doesn't know whether you mean the global doSomething() or the one in namespace foo.
ah Gotcha thanks !
Sorry Alex, maybe because my English is so bad so I can't understand with this sentence "This includes header files!" In the using keyword section, specifically at there "Rule: Don’t use the “using” keyword in the global scope. This includes header files!".
Is it mean we shouldn't includes header files in global scope? Or we shouldn't use the using keyword in header files? Or what?
Thank you.
Don't put using statements in header files (unless they're inside a function that is defined in the header file). Otherwise when you #include the header file, the using statement will be copied into the global scope of every file that includes that header.
Alex, i think that you forgot to end something to put a line in bold. I mean after this line :
"Nested namespaces and namespace aliases"
the rest of the lesson and all the comments are in bold.
It looks fine to me, both rendered and in markup. Is anybody else seeing anything weird?