Home > Mobile >  Why do we need to specify namespace if we also need to include standard library headers?
Why do we need to specify namespace if we also need to include standard library headers?

Time:05-19

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.

CodePudding user response:

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.

CodePudding user response:

cout is an object of type basic_ostream<char>(aka ostream) and this ostream is a specialization for the char type 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;
}

CodePudding user response:

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.

CodePudding user response:

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.

  •  Tags:  
  • c
  • Related