Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Structure of std::endl [duplicate]

I am new to C++ and I am confused about std::endl. When trying to understand what std::endl is, I had faced some resources which told me that it is a function.

However, how can a function be deprived of parentheses?

like image 438
Goktug Avatar asked Sep 21 '17 11:09

Goktug


2 Answers

Read the ref:

std::endl

Inserts a new-line character and flushes the stream.

It's used with a stream, for example std::cout.

It's not a function, it's a function template.

std::endl without parentheses refers to a set of overload functions - all possible specializations of that function template. Read more in How does std::endl not use any brackets if it is a function?

like image 177
gsamaras Avatar answered Nov 14 '22 10:11

gsamaras


However, how can a function be deprived of parentheses?

The name of a function, without being followed by (), is just a reference to that function. It's exactly the same as with any other type:

void foo(int) {}

char x = 'a';

char *p = &x;

int main()
{
  p;  // Refers to p
  *p; // Dereferences p (refers to whatever p points to)
  foo;  // Refers to foo
  foo(42); // Calls foo
}

std::endl is a function (actually a function template) which takes one parameter of type "a stream", and works by inserting an EOL representation into that stream and then flushing it. You can actually use it like any other function, if you want to:

std::endl(std::cout);

The final piece of the puzzle is that the standard library provides an overload (again, a template) of operator << such that the LHS argument is a stream and the RHS argument is a function; the implementation of this operator calls the RHS argument (the function) and passes it the LHS one (the stream). Conceptually, there's something like this:

Stream& operator<< (Stream &s, const Function &f)
{
  f(s);
  return s;
}

Therefore, calling std::cout << std::endl invokes that operator overload, which in turn invokes std::endl(std::cout), which does the EOL insertion + flushing.

As to which form is to be preferred (direct call vs. << operator), it's definitely the use of <<. It's idiomatic, and it allows easy composition of multiple stream manipulators within a single expression. Like this:

std::cout << "Temperature: " << std::fixed << std::setprecision(3) << temperature << " (rounds to " << std::setprecision(1) << temperature << ')' << std::endl;
like image 26
Angew is no longer proud of SO Avatar answered Nov 14 '22 09:11

Angew is no longer proud of SO