0

Just started collage and I'm new in the world of programming. So, as I was learning C++ I bumped into a question that wouldn't let me be : "Why do i need to include "using namespace std" in my code to be able to write or read if i already got iostream?" , because I've been told that "cin/cout" are already defind in iostream library, but I noticed that if I write one of these lines alone it will give a compilation error. And ,therefore, what's the relation between iostream and "std" namespace ...Can someone explain , please? Thank you! <3

Robert
  • 71
  • 8
  • 3
    "Why do i need to include "using namespace std" - You *don't*. – Jesper Juhl Aug 27 '20 at 18:24
  • 1
    please read this, it is important that you understand that your premise is false: [Why is “using namespace std;” considered bad practice?](https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice) – 463035818_is_not_an_ai Aug 27 '20 at 18:25
  • 1
    [Why is "using namespace std;" considered bad practice?](https://stackoverflow.com/q/1452721/5910058) seems relevant.. – Jesper Juhl Aug 27 '20 at 18:25
  • Generally, namespace and library are related 1-to-1. For example, the standard library defines everything in the `std` namespace. – rustyx Aug 27 '20 at 18:30
  • `#include int main() { std::cout << "Hello world\n"; }` - See. No `using namespace ..`. – Jesper Juhl Aug 27 '20 at 18:30
  • @rustyx Sorry to be pedantic, but that's not strictly accurate. A library like Qt does not use namespaces *at all*, but instead prefix all their class names with "Q". And the standard library contains a few things that live in the global namespace rather than "std" and some things in nested namespaces (like "std::chrono"). – Jesper Juhl Aug 27 '20 at 18:34
  • you can get it with a little "google it" effort, no need to ask a new question of already "easy google questions" – AAEM Aug 27 '20 at 19:04

4 Answers4

3

#include vs using

In simple terms:

#include <iostream> // include the header

int main() {
    // now you can use stuff declared in that header
    std::cout << "Hello world" << std::endl;

    // if you are lazy you can "use" things:
    using std::cout;
    using std::endl;
    cout << "Hello World" << endl;
}

You do not have to write using namespace std;! The cases where it is appropriate to do that are so rare and the cases where it really does great harm are so frequent that as a rule of thumb you can remember: Never use it! For details see here: Why is “using namespace std;” considered bad practice?. It is imporant to realize that the difference between fully qualifying a name, std::cout, and not fully qualifying the name, cout, is not just about typing 5 characters more or less (read on...).


libraries vs namespaces

What's the relation between libraries and namespaces?

The standard library puts everything in the std namespace. Namespaces help to keep things separated. A different library can contain a other_namespace::vector and there will be no confusion with std::vector because we have namespaces.


the really cool stuff

One deeper reason to use namespaces is Argument Dependent Lookup. I will try to explain with a simple example. Suppose you are using a library with some function template that does something with objects of a type you will have to supply:

namespace library {
    template<typename T>
    void do_something(T& a,T& b){
        std::cout << "wrong...\n";
        std::swap(a,b);    // (1) 
        std::cout << "correct\n";
        using std::swap;   
        swap(a,b);         // (2)
    }
}

I takes two objects and swaps them twice. You have to bear with me for second to understand why (1) is wrong and only (2) is correct. For now we have a library function template and to use that we need some type T:

namespace A {
    struct foo{};
    void swap(foo& a,foo& b) {
        std::cout << "A::swap" << "\n";
    }
}

Imagine foo is such that we know a better way than std::swap to swap to instances. Actually foo is empty, so to swap two objects we have to do nothing.

Lets recap: There is std::swap that comes with the standard library. Someone wrote a library (called library) we want to use. We want the library code to call A::swap instead of std::swap. The library author doesn't even know that A::swap exists.

Together with above A and library, this code

int main() {
    A::foo a,b;
    library::do_something(a,b);
}

will print:

wrong...
correct
A::swap

Live Example. What happened? This line:

std::swap(a,b);    // (1) 

calls std::swap, no doubt. Not what we want. We would like the library code to call our A::swap.

Now this:

using std::swap;   
swap(a,b);         // (2)

The first line pulls the name swap from std into the scope of the function. In the second line finally ADL kicks in because it says swap not std::swap. ADL in a nutshell is: a and b are from namespace A, so when the compiler searches for all possible swaps it also searches in A. If it finds one in A then it calls that (and if it does not find one in A there is still the swap coming from std). Hence only (2) calls our custom swap.

This can only work with namespaces. The "cool stuff" is that the library author does not need to know anything about your namespace but still their library code will call your function from your namespace if it exists.

I should note that not all code is generic library code. Often you want to write code where you know what happens in each detail, you want to know what functions get called. Often you do not want your code behave differently depending on a specific header being included or not. Hence, lots of code is better off with fully qualifiying function calls: std::foo.


conclusion

I hope that I could convince you that namespaces is not just about typing some characters more or less. using namespace std; for lazyness completly misses the point of namespaces. On the other hand, pulling names into scope via using std::foo; foo(); is completely fine and enables ADL.

463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185
  • yeah, but also.. why do we need to use std:: if cout and cin is defined in iostream... – Robert Aug 27 '20 at 18:31
  • 2
    @Robert because thats their full name. Why do I call you Robert and not bert? – 463035818_is_not_an_ai Aug 27 '20 at 18:34
  • It's funny that you say, *This should be covered in an introductory book* because in Stroustrup book *Programming Principles and Practice Using C++* he actually uses `using namespace std;`. However, he does mention like you said, to avoid *using* directives for any namespace except for a namespace such as *std*. But I agree with you that you should just all together avoid `using namespace std;`. Just thought I should mention. – Geno C Aug 27 '20 at 18:48
  • 1
    @GenoC I am really curious to know what Bjarne would say for his defense. The usual argument goes like this: It is ok to `using namespace std` in short example or on presentation slides where space is extremely limited. The reader is assumed to know that this is just for presentation and not for real code. – 463035818_is_not_an_ai Aug 27 '20 at 18:50
  • @idclev463035818 I agree! – Geno C Aug 27 '20 at 18:54
  • @Robert like idclev said, *it is their full name*. Also worth noting, that these colons `::` are called *scope resolution operator*. Which means when you compose a namespace name, `std` and say a member name like `cout` together like so: `std::cout` it is said to be a *fully qualified name* – Geno C Aug 27 '20 at 19:00
  • @GenoC OHHH! ...so practically "std" namespace contains all STANDARD LIBRARY code? RIGHT? .. sorry if im asking dumb questions , I' m a newbie :D – Robert Aug 28 '20 at 19:06
2

Libraries and namespaces are related by convention.

By convention, the symbols that a library provides to the programmer-user are contained in a namespace. This organizes things, and there are some higher level language features (ADL) that mean code in a namespace behaves differently than code outside of it.

When you type using namespace std; you tell the compiler "when you run into a symbol, also look into std to find if you can determine what it is". It is generally a really really bad idea to do this at "file" scope; doing it within a single short function is usable, but any more than that can lead to really tricky bugs.

The standard, professional way to interact with namespace std is to prefix your symbols with the namespace:

std::cout << "Hello world\n";

rather than

using namespace std;
cout << "Hello world\n";

and definitely never:

using namespace std;
int main() {
  cout << "Hello world\n";
}

you can also grab single symbols, which isn't as bad as importing an entire namespace:

using std::cout;
cout << "Hello world\n";

but should also be avoided at "file" scope.


#include <iostream>

this includes the header file named iostream from the system search path. iostream is part of the standard library. By convention (and the C++ standard), the symbols that iostream provides your program with are located within namespace std.

By putting symbols in a namespace, you avoid conflict with your code. There are many, many symbols in std, and if #include <iostream> shoved some unknown number of symbols into your global namespace, you could easily get errors or the wrong function called in unexpected ways.

std::cout and using namespace std; cout and using std::cout are all ways to tell the compiler in what namespace to find the symbol cout.

#include <iostream> includes cout in namespace std; without it, your code is unaware of its existence.

C++ developed from C, and C has a textual inclusion model. #include actually takes the content of the file iostream and copy/pastes it into your file. Your compiler then reads that extended file and finds the symbols in <iostream>.

Because this textual inclusion could shove a LOT of stuff, having it isolated to a namespace prevents problems for you, the programmer.


Recently, C++ has added modules. Modules are an alternative to #include directives, in that it directly grabs symbols from a library and injects it into your code without a huge copy paste.

In modules, namespaces are still not directly connected to the module. You can

import std;

or

import std.iostream;

and that will just import the std library symbols, still in namespace std, into your code. (the C++ standard added modules, but did not modularize the std library yet, so those names above are speculation).

The symbol lookup is not directly connected to the symbol import.

This lets symbol import be done in large chunks, while lookup be done more carefully.

Yakk - Adam Nevraumont
  • 262,606
  • 27
  • 330
  • 524
  • I partially understand this but there is one more thing.. namespaces are defined in libraries or vice-versa or they are separately defined but with some references to each other? – Robert Aug 27 '20 at 19:08
  • @Robert They are only related to libraries by convention. By convention, people writing libraries put code into a namespace. You can write your own namespace in your own `cpp` file `namespace bob { struct hello {}; }` and another `namespace alice { struct world {}; }` which makes two symbols called `bob::hello` and `alice::world` that name (empty) structs. – Yakk - Adam Nevraumont Aug 27 '20 at 19:15
0

iostream is a library. It's code someone has written for you so you don't have to do it. By adding #include <iostream> you tell the preprocessor to paste in that code. But the functions and structures that are provided by this code might have names that interfere with others. But that isn't a problem because you can just separate them by putting them in a namespace, the STL(which upstream is part of) does this with std(short for standard, pronounced as 'stood'). When something is in a namespace, you must name that namespace to access stuff in that. i.e. std::cout. But sometimes you don't want to have to write std:: every time you want to access something from the STL. That's what using namespace std does for you. That way, you can just type cout. But this is a very bad idea!

Nikita Demodov
  • 553
  • 5
  • 17
  • 1
    fwiw I think the guy in the video misses the real problems with `using namespace std;`. He is mainly arguing with style and readability... – 463035818_is_not_an_ai Aug 27 '20 at 18:38
  • Why cin and cout causes confusion so that they need to be separated in namespaces? Aren't them made just for one thing... write /read? – Robert Aug 27 '20 at 18:56
  • 1
    @Robert assume you write your own `cout`, because you put it in your namespace you then have `roberts::cout` and `std::cout`, without namespaces you would have `cout` and `cout`. There is a huge number of names in `std`, nobody can remember them all, so it would be impossible to avoid clashes when there were no namespaces – 463035818_is_not_an_ai Aug 27 '20 at 19:03
0

Libraries

Libraries have portions of codes pre-written to provide you with functionalities. Could be in the form of functions/overloaded operators etc.

There are two types of libraries:

  1. Standard Libraries e.g. #include <iostream> and the name of library is in angle brackets.

  2. User defined/made e.g. #include "randomLib.h" and the name of library is in double quotes.

Namespaces

When you require multiple libraries for your project. There is possibility that the both may include multiple methods (function definition) with the same name or a single library may use same function names but in different namespaces. Namespaces are there to remove the confusion or ambiguity for the compiler and user.

  1. Lets say lib 1 has namespace abc{ foo(); } and lib 2 has namespace def{ foo(); }

So you will do abc::foo() or def::foo() for you required functionality. Here abc/def is the namespace, :: is called scope resolution operator and foo() is the method you are calling.

vhmvd
  • 192
  • 3
  • 15