質問: 2017/03/24 12時24分 ベストアンサーについて:予想を超え、様々な人でこの回答作りあげている質問になりました。そのため、とてもベストアンサーが選びづらかったです。ですが、teratailから催促メールも来ますし、投票の一番多い、faithandbraveさんにベストアンサーを決定しました。活発な議論がとても楽しかったです。皆様ありがとうございました!
回答: オーバーロードは本来、意味論が同じものをまとめるためにあります。そういう理由で、`operator<<`をビットシフト以外の意味で使用するのを忌避するのは理解できます。 `operator<<`を採用したのは、『C++の設計と進化』の「8.3.1 ストリームI/Oライブラリ」に記載されているように、UNIXのI/Oリダイレクト演算子にあやかったものです。 しかし、より技術的な理由は、型安全な可変引数がなかったことによるものでしょう。C++11段階であれば可変引数テンプレート、constexpr、リテラル演算子がありますので、`operator<<`に頼ることのない、より使いやすいI/Oのライブラリを設計できます。つまり、現在のI/O標準ライブラリについては、単に設計が古いです。具体的には、`printf`はフォーマットが文字列になっていてそれがコンパイル時に解決できないことが問題ですので、フォーマット文字列をコンパイル時に検証し、かつパラメータ数が可変個受け取れればいい、というものです。 演算子オーバーロードの設計思想は、組み込み型と同じことをユーザー定義型でもできるようにすることです。そのため、組み込み型でできないカスタムの演算子というのは定義できないようになっています(HaskellやScalaと違って)。基本的にはこれに従い、そのときの言語機能で、その枠からはみ出ざるを得ない状況でのみ独自の名前空間内で独自の意味を持たせることになるでしょう。 演算子オーバーロードは、`a.Add(b)`を`a + b`のように変換し、「冗長」という問題を解決するためにも使用できます。既存の意味から外れる演算子オーバーロードは、主な目的は冗長さ問題の解決にあります。 演算子オーバーロードの制限や不利な点は、以下のようなところです: * 規定の個数を超えるオペランドを扱えない たとえば、配列において`ar[i]`はできますが、行列型に対して`m[x, y]`のような指定はできません たとえば、浮動小数点数の等値比較において`a == b`という2つのパラメータしか扱えないため、誤差をどこまで許容するか、のようなパラメータは指定できません * ADLに依存してしまう * 短絡評価をハンドリングできない (`operator||`、`operator&&`) * 組み込み型の演算子と意味論に制限されてしまう C++以外の分野(たとえば数学)で広く採用されている演算子があり、それを採用できない 例として、累乗を扱う`**`演算子や、論理学で「PならばQ」を表す`→`演算子、ディレクトリ区切りの`/`、区間を表す`[a, b)`のようなカッコなど、やりたいことは無数にあります 演算子に独自の意味を持たせるためのルール付けが何かしらあれば、特定分野のコードがより書きやすくなるでしょう 参照 * Boost Filesystem Library * Boost Spirit Library * Logic paradigm for C++ * fmtlib