Why do I have to write std::cout
and not also std::<<
in a line of code like this:
#include <iostream> int main() { std::cout << "Hello, world!"; return 0; }
cout
comes from std
library, and isn't <<
usually used to do bits shifting? So, why don't I have to write the scope operator ::
also before <<
, since it is used also with another meaning? How the compiler knows that after std::cout
, <<
means another thing?
Difference between cout and std::cout in C++ The cout is a predefined object of ostream class, and it is used to print the data on the standard output device. Generally, when we write a program in Linux operating system for G++ compiler, it needs “std” namespace in the program.
The string and vector which we want to use are in the C++ standard library, so they belong to the std namespace. This is why you need to add std:: to them. It is the same reason to use std:: for cout and cin .
It is not necessary to write namespaced, simply use scope resolution (::) every time uses the members of std. For example, std::cout, std::cin, std::endl etc.
You do not need using namespace std , and you shouldn't use it. Use fully qualified names std::cout and std::endl , or, in a small scope, using std::cout; using std::endl; As for the other questions, std::cout is not a function.
First, the compiler will look at the types to the left and right of <<
. std::cout
is of type std::ostream
, the string literal is of type array of 15 const char
. As the left is of class type, it will search for a function named operator<<
. The question is, where will it look?
The lookup for this name operator<<
is a so-called unqualified lookup, because the function name isn't qualified like std::operator<<
. Unqualified lookup for function names invokes argument-dependent lookup. The argument-dependent lookup will search in the classes and namespaces associated with the argument types.
When you include <iostream>
, a free function of the signature
template<typename traits> std::basic_ostream<char, traits>& operator<<(std::basic_ostream<char, traits>&, const char*);
has been declared in namespace std
. This namespace is associated with the type of std::cout
, therefore this function will be found.
std::ostream
is just a typedef for std::basic_ostream<char, std::char_traits<char>>
, and the array of 15 const char
can be converted implicitly to a char const*
(pointing to the first element of the array). Therefore, this function can be called with the two argument types.
There are other overloads of operator<<
, but the function I mentioned above is the best match for the argument types and the one selected in this case.
A simple example of argument-dependent lookup:
namespace my_namespace { struct X {}; void find_me(X) {} } int main() { my_namespace::X x; find_me(x); // finds my_namespace::find_me because of the argument type }
N.B. As this function is a operator, the actual lookup is a bit more complex. It is looked up via qualified lookup in the scope of the first argument (if that's of class type), i.e. as a member function. Additionally, unqualified lookup is performed, but ignoring all member functions. The result is slightly different, because unqualified lookup is actually like a two-step procedure, where argument-dependent lookup is the second step. If the first step finds a member function, the second step is not performed, i.e. argument-dependent lookup is not used.
Compare:
namespace my_namespace { struct X { void find_me(X, int) {} void search(); }; void find_me(X, double) {} void X::search() { find_me(*this, 2.5); // only finds X::find_me(int) // pure unqualified lookup (1st step) finds the member function // argument-dependent lookup is not performed } }
to:
namespace my_namespace { struct X { void operator<<(int) {} void search(); }; void operator<<(X, double) {} void X::search() { *this << 2.5; // find both because both steps are always performed // and overload resolution selects the free function } }
In std::cout << "Hello, world!"; //calls std:::operator <<
This is achieved with Argument-dependent name lookup (ADL, aka Koenig Lookup)
Although we have only one std
qualifier but there are two things that comes up from std
namespace
cout
<<
Without ADL, (Koenig Lookup)
std::cout std:: << "Hello World" ;//this won't compile
In order to compile it, we need to use it more uglier form
std::operator<<(std::cout, "Hello, world!");
So to avoid such ugly syntax we must appreciate Koenig Lookup :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With