Hello, World!
C++入門書の冒頭で必ず目にするソースコード。
🤬「文字列表示に<<
って何だよこれ!」
#include <iostream>
int main()
{
std::cout << "Hello, World!" << std::endl;
}
現在では悪評高い1C++標準ライブラリのストリーム出力演算子<<
ですが、C++黎明期においては一定の妥当性がある選択でした。
- C言語
printf
の問題点を解決する- 型安全性(Type Safety) を実現すること
- ユーザ定義型に対して 拡張可能 であること
- 特別な言語拡張を必要とせず ライブラリ実装可能 であること
"It's easy to criticize in hindsight."
「後から振り返って批判するのは簡単だ」
We're living in 2024.
C++23標準ライブラリでは<print>
ヘッダにより型安全・拡張可能なprint
/println
関数が追加されますから、I/Oストリームに不満をぶつけるよりもモダン機能を積極利用しましょう。
#include <print>
int main()
{
std::println("Hello, World!");
}
P.S. C++20/C++23がまだ使えない環境でも {fmt}ライブラリ の利用をぜひ検討ください。MIT License.
参考文献
A History of C++
C++の生みの親である Bjarne Stroustrup 氏により公開された A History of C++: 1979-1991 より引用。
5.3.1 The Stream I/O Library
Type-security and uniform treatment can be achieved by using a single overloaded function name for a set of output functions. For example:
put(stderr,"x = "); put(stderr,x); put(stderr,"\n");
The type of the argument determines which "put function" will be invoked for each argument. However, this is too verbose. The C++ solution, using an output stream for which
<<
has been defined as a "put to" operator, looks like this:cerr << "x = " << x << "\n";
where
cerr
is the standard error output stream (equivalent to the Cstderr
). So, ifx
is anint
with the value123
, this statement would printx = 123
followed by a newline onto the standard error output stream.
This style can be used as long as
x
is of a type for which operator<<
is defined, and a user can trivially define operator<<
for a new type. So, ifx
is of the user-defined type complex with the value(1,2.4)
, the statement above will printx = (1,2.4)
on
cerr
.The stream I/O facility is implemented exclusively using language features available to every C++ programmer. Like C, C++ does not have any I/O facilities built into the language. The stream I/O facility is provided in a library and contains no "extra−linguistic magic".
The idea of providing an output operator rather than a named output function was suggested by Doug McIlroy. This requires operators that return their left−hand operand for use by further operations.
C++ View Interviews
インタビュー記事 C++ View Interviews Bjarne Stroustrup より引用。
The key decisions was to separate formatting from buffering, and to use the type-safe expression syntax (relying on operators
<<
and>>
). I made these decisions after discussions with my colleague Doug McIlroy at AT&T Bell Labs. I chose<<
and>>
after experiments showed alternatives, such as<
and>
, comma, and=
not to work well. The type safety allowed compile-time resolution of some things that C-style libraries resolve at run-time, thus giving excellent performance. Very soon after I started to use streams, Dave Presotto transparently replaced the whole buffering part of my implementation with a better one. I didn't even notice he'd done that until he later told me!
The Design and Evolution of C++ (C++D&E)
Bjarne Stroustrup 氏自身による書籍 The Design and Evolution of C++ 原著 (StackOverflow回答) および (日本語訳版) C++の設計と進化 より引用。
The idea of providing an output operator rather than a named output function was suggested by Doug McIlroy by analogy with the I/O redirection operators in the UNIX shell (
>
,>>
,|
, etc.)
名前のある出力関数ではなく出力演算子を提供しようというアイデアは、Doug McIlroyが提案した。そのヒントは、UNIXのI/Oリダイレクト演算子(
>
,>>
,|
,など)だ。
-
インターネッツ調べ。検索すればたくさんの怨嗟の声が見つかるはず。 ↩