0

Completely new to C++, but have done some work in C. Have just seen the Hello, World example:

#include <iostream>
int main() {
  std::cout << "Hello, World!" << std::endl;
  return 0;
}

My question is why we must specify that cout is from the standard library, when I have already included the declarations for cout from the iostream header file?

I suspect that it's so that if we had another header file, say myFirstHeader.h, which also had a cout identifier, it would avoid ambiguity about which cout is being used?

Appreciate any help or redirection.

articuno
  • 5
  • 2
  • 2
    Because `cout` isn't declared in the global namespace, but in the `std` namespace (just like you can declare your own namespaces and define functions and classes and objects in them)? Also see the very related [Why is "using namespace std;" considered bad practice?](https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice?rq=1) Perhaps [a good C++ book](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list/388282#388282) might help you understand namespaces a little better. – Some programmer dude May 19 '22 at 06:01
  • 8
    `cout` may be unlikely to be used as an identifier in another namespace, but the `std` namespace contains plenty of identifiers where that sort of ambiguity is very possible. `pair`, `complex`, `count`, `find`, `search`, `copy`... And just in general I personally find the `std::` prefix to be useful when reading code as a way of identifying "Hey, this bit's from the standard library". – Nathan Pierson May 19 '22 at 06:06
  • 2
    The main point of *namespces* is so that when you `#include` a library, its function names won't clash with other libraries that you `#include`. So everything from the library is in the *namespace* of that library. Otherwise, you may have trouble using two different libraries that use the same function name. – Galik May 19 '22 at 06:34
  • The decision to put symbols into the namespace `std` was made by the standard library makers (to avoid current and future clashes). Other libraries could handle it differently, it is not enforced by the language itself. You can do the same with your code. There are ways to import all symbols from std into the current namespace (`using namespace std` or just specific ones (`using std::cout`). – Sebastian May 19 '22 at 07:06
  • @Galik - It's not just function names. It is any name used in the library (for functions, types, variables, ..... ) other than macros (which cause clashes, regardless of use of namespaces). – Peter May 19 '22 at 07:06
  • I think `articuno` has some experience with language where importing is not needed it is enough to use in place of use its full path/mamespace/package to get it. Namespaces ins C++ are independent form libraries. You can have to libraries using same namespace or one library having multiple namespaces. Reasons are more historic starting from "C with Classes" in 1979. – Marek R May 19 '22 at 08:00
  • It is like a file system - you mount it and additionally have to specify the directory and/or drive letter instead of all files ending up together in the root directory. – Sebastian May 19 '22 at 08:10
  • Its fine to ask basic question on this platforms. But before asking you shall check whether the similar Q&A already happened on same topic or not. If yes you can take reference of same and come up with a better query. I hope just before submitting the question you must have gotten some duplicate links, make a practice to go through those first if helpful. – Achal May 19 '22 at 09:20
  • 1
    @Sebastian The follow up example in the most upvoted reply was super! Thanks for sharing <3 – articuno May 19 '22 at 13:58

4 Answers4

4

Generally namespaces prevent name clashes between different modules or libraries. Now you might say that the std namespace is the standard that everyone uses so nobody should name their variables, classes or functions to clash with the standard.

But that is short sighted. What is used in todays standard is not the same as yesterdays standard or tomorrows standard. The standard changes and things are added over time (and sometimes removed). So any variable, class or function you use today could have a name clash tomorrow.

Having the namespace std avoids that problem because it will never clash with anything you define outside the namespace std.

Plus std::... automatically tells me where to find the documentation when I see some unknown thing and tells me it's not something thought up by the project I'm looking at.

Goswin von Brederlow
  • 11,875
  • 2
  • 24
  • 42
1

cout is an object of type basic_ostream<char>(aka ostream) and this ostream is an alias for the specialization basic_ostream<char> of the class template basic_ostream.

why we must specify that cout is from the standard library, when I have already included the declarations for cout from the iostream header file?

The important thing to note here is that ostream lives in namespace std and not the global namespace. So to create and use an object of type ostream from the std namespace we have to be in that namespace which we do by qualifying the name with std using the scope resolution operator ::.

Perhaps a contrived example might help clear the picture:

namespace Custom  //Custom is a namespace 
{
    struct Person //Person is a type 
    {
        
    };
    Person B; 
}
int main()
{
//--vvvvvvvv------------>for creating an object of type `Person` we have to be in the namespace in which the type `Person` exists
    Custom::Person p;
    
//--------------------vvvvvvvvv-------------->even for using object `B` which exists in namespace `Custom` we use the qualification `Custom::` 
    std::cout<<sizeof(Custom::B)<<std::endl;
    return 0;
}
Jason
  • 36,170
  • 5
  • 26
  • 60
1

Adding to Goswin's valid answer:

First - you don't have to use std::endl; that's a shorthand for saying:

std::cout << '\n' << std::flush;

and you don't need to flush, since you're just about to finish the program - and the standard output stream gets flushed on exit.

Now, about the prefix: if you're writing a specific function in a file, and you're in control of which names are visible in there, you can shorten your names, in one of several ways:

  1. A specific using statement:

    int main() {
        using std::cout;
        cout << "Hello, World!\n";
     }
    

    (not very useful when you're only using an identifier once

  2. An reference serving as an alias:

    int main() {
        auto& stream = std::cout;
        stream << "Hello, World\n;"
    }
    

    this does not result in any extra copying, resource allocation etc.

einpoklum
  • 118,144
  • 57
  • 340
  • 684
0

The C++ identifiers must be qualified with their namespace. By adding a "using namespace" clause, you can let the compiler supply the namespace itself. And of course in case of ambiguities, you need to resolve explicitly.

  • Please don't suggest OP add `using namespace std`, that's a [bad idea](https://stackoverflow.com/q/1452721/1593077). – einpoklum May 19 '22 at 10:10
  • @einpoklum: that's an opinion. –  May 19 '22 at 10:12
  • A compromise could be too list each identifier with 'using std::cout; using std::endl;' and so on individually, but then it looks like the pages of Java imports at the beginning of source files, when the IDE add the imports without .* ... – Sebastian May 19 '22 at 11:41
  • Another way is to put the `using namespace` just inside each function scope. What is quite often agreed on is that it should not be used in headers (especially ones imported by many .cpp files). – Sebastian May 19 '22 at 11:42