CR/LF codes are an anachronism. The first terminals were teletype machines evolved from manually-operated typewriters. They printed results on actual paper.
On a typewriter, a carriage carrying a spool of paper moves from right-to-left across the print head as keys are depressed. When the carriage moves fully to the left, the user must unroll a little more paper and physically push the carriage to the right. See:
https://www.youtube.com/watch?v=EiyZSX0OnBM
Very old teletypes were essentially electronic typewriters. The computer communicated with the user by typing, and would feed the line or return the carriage only when a line-feed (LF) or carriage-return (CR) code was sent over the wire.
https://www.youtube.com/watch?v=S81GyMKH7zw
Later systems retained the separation between LF and CR for compatibility reasons.
So that's why LF and CR exist. They're important today because '\n' is a notation introduced by C: there is no new-line character in ASCII. Therefore, the standard library must translate '\n' into the sequence of bytes which best represents "newline" on the system.
Microsoft Windows represents a new-line in bytes by a carriage return code followed by a line feed, while Unix typically uses only one line feed. Old Mac programs used only a carriage return, but now Mac has joined with Unix.
Therefore, when you say
text_file << '\n';
It tells the C++ library "I want a newline", and the C++ library does whatever it needs to do to make sure that the bytes in text_file represent a new line.