現代のC++

C++17での機能追加について、ネット上では「項目一覧見ただけで読む気失せる」「入門不可能」「闇」「誰も使いこなせない」「絶対に使いたくない」などと盛り上がっている。

だが私は一概にはC++はどんどん初心者を見捨てているとは言えないと思っている。C++は規格のアップデートの度に、その場しのぎだったり一貫性を欠いたりするルールを廃し(vector<vector<int> >の空白や、template template parameterにtypenameを許可など)、より意図が明快で細かいことを考えなくていい文法が追加され(型推論、構造化束縛、range-based forなど)、古式ゆかしい形式よりも安全で使いやすいライブラリ(optional、string_viewなど)が追加されてきた。たまにC++98を使うとよくわかるが、最新のC++はかなりユーザーに優しい。

つまりどちらかというとC++はアップデートの度にユーザーの方に寄ってきているのだ。ユーザーが欲していた機能を追加し、ユーザーの評判が悪かった機能を捨てて。捨てることになったものを中々本当には切り離さないので(トライグラフは誰が使っていたのだろう)外から見ていると肥大化しているように見えるが、使っている側としてはどんどん便利になってきていると感じている。むしろ、単に使うだけの静的スクリプト言語という用途にすらなり得ると思っている。インタプリタないけど(CLing使ったことなし)。

どんなコンパイラを使わせてもらえるか・どんな人と共に働くかは言語の話ではなく環境と人間社会の話なのでここではしない。

しかし実際、言語規格書が4桁ページあるという事実や特筆すべき言語機能・標準ライブラリが目次だけで10回スクロールしなければならないくらいに山ほどあるというのは、初心者をひるませるのに十分だ。だが待ってほしい、規格書に目を通すユーザーが一体何人いるというのか? 都度リファレンスを検索するだけにとどまらず、ライブラリ全てに目を通すユーザーは? はっきり言って入門のしやすさに規格書の分厚さは何の関係もないと思っている。そもそも言語規格が文書化されていない言語もある。ユーザーが規格書の分厚さでひるむというなら、リファレンス処理系が言語標準になっている場合、ユーザーは処理系の行数で学ぶ言語を決めるのだろうか。そんなはずはない。

どちらかというと、C++の難しさは、よくある入門書の内容や、さらっと検索した時に出てくる記事が専門的すぎることに起因するのではないだろうか。C++の入門書はどれも分厚い。Cを知っている前提で書かれた本であっても分厚い。blog記事にはちょいちょい不正確な内容が含まれていたり、入門者には理解不能な内容だったりする。耳が痛い。

ところで、現代でC++だけでなくプログラミング自体を学ぼうとしている初心者が、自分でnew/deleteを使わなければならないケースはあるだろうか。いやmalloc/calloc/realloc/freeを使うとかではなく。

かなり特殊なケース(情報工学系にいて新規なアーキテクチャを開発中だがプログラミングはしたことがない、などがパッと思いつくがそんなことがあり得るだろうか)でない限り、多分ないと思う。可変長配列は普通vector一択だろうし(dequeなどもあるが)、新規リソース確保はスマートポインタを使うべきだ。以前取り上げたケースである安全にunionを使いたい場合でも、C++17にはvariantがある。明示的な初期化をせずにただメモリ確保したい場合というのは、多分初学者にはない。むしろ未初期化変数を参照してバグを作る初学者をたくさん見てきた。

よって、極論を言うと、現代のC++の入門書においてはnew/deleteは扱わなくていいだろう。コラム的に扱っておしまい、で良い気がする。むしろ初学者がよくわからないままにnew/deleteを使うと弊害の方が大きいのではないか。

また、配列に関しても、std::arrayを紹介して終わりでいいと思う。そうすれば、配列の参照やポインタや関数から返すことなどの問題に悩まされることは減るし、パフォーマンスが低下するわけでもない。

他にも、例えばstd::vectorstd::allocatorの話を全く知らなくても使える。std::vectorを使うときにAllocatorのことを頭に置くのはよほどのパフォーマンスフリークかライブラリアンだけで、忘れ去るどころか一切知らなくとも入門はできるのである。内部の散策、特に岩をひっくり返して下にどんな生き物がいるか観察する、などは入門した後ですれば良い。

そういうことを考えていくと、C++の「入門不可能言語」という認識は、

  1. 入門書の網羅性が高く、基礎からやり過ぎる
  2. 専門性の高い本やエントリが多く、敷居が高く感じる
  3. Cのコードや古い規格のコードが混ざることによる前提知識の増加

あたりが原因なのではないかという気がしてくる。

もちろんC++をやるということはパフォーマンスが重要なプログラムを柔軟に書きたいということであり、その点では特化型の専門書や高度な技術エントリの存在は欠かせないだろう。また、C時代の遺産を使いたいという場合もあるだろう。しかし入門書で別の言語と同時に使うやり方を書くような本があるだろうか。それらは入門してから個々の分野をゆっくり学べばよいので、入門書からはそのような内容は削り取れる。書いてもコラムや付録などで少し触れ、そこでよい書籍を紹介するという形で十分ではないか。

専門性の高い本が多いことで困る一番の理由は、簡単になったと聞いて勉強しに来た人を圧倒的な前提知識の要求で吹き飛ばしてしまうことだと思っている。骨のある人間なら(悪く言うとマゾヒスト)頑張って勉強してついていこうとするだろうが、ついていくメリットがわからなかったら釣り合わないように思えるような多大な努力はできないだろう。そして既によく知っている人間か、よほど必要に駆られている人でないかぎり、あまりに高度になっていく話に無理に着いて行くメリットは感じられない。

大雑把に言えば、C++11/14/17の話は、それまでのC++をかなり知っていることを前提にした上で、「こうしたければ、昔はこうしていた(入門者には意味不明)のを今はこうできる」とか、「新しいこの形式は古い場合のこのコード(入門者には意味不明)と等価になる」という形になりがちなので、それを単に何の前提知識もおかず、そもそもC++とは最初からそういうものだったかのように、「こうしたければ、こうできる」というだけの入門書があれば喜ばれるのではないかとも思う。

問題は有り難みが薄れるということだが。AとBとCを統一的に扱えるようにした、というような話は、A,B,Cをより古いスタイルで別個に使ってきた人には有益さがすぐにわかるが、そうでない人にはすぐにはわからない。ハードウェアレベルの現象を非常に細かく操れることも、ハードウェアと低水準言語を学んだ人には高級言語のやり方でそれを操れる有り難みがわかるが、そうでない人には意味不明な機能がある、という以上の情報にはならない。しかし私は、無理に不便な時代の話や普段は隠されている複雑な話をしてまでその利便性を説明しなくてもいいのでは、とも思うのだ。特に入門書なら、サラッとこういう点で便利ですと単に言うだけ、或は完全に飛ばしてしまってよくて、不便だった頃の話はしなくてもよいのではないか。知るべき時が来たら知るだろうし、知らなくて済むなら不便なことは知らなくていい。

なので、あたかも「簡単な言語」であるかのように、便利な部分のみを語って、不便だった時代のことを忘れてしまえば、そして入門書であまり細かい話をしないようにすれば、C++は十分「簡単で速い言語」の地位を得られるのではないかと思う。まあ、深入りすると帰ってこれないのは如何ともしがたい事実だが……。それは深入りしなければいいだけの話だ。簡単な言語・入門用言語として知られている言語も大抵、変な方向に深入りすると結構ヤバい。

C混じりのC++C++98/03時代のコードなどについては、入門書では少なくともメインで古い時代の話をする必要はない。これもコラムや付録へ追いやれるだろう。付録に入れたとしてもさわりだけ話して別の本へ転送すれば良い。興味がある人は読むだろうし、興味がない人は単に必要になるまで遅延すれば良い。必要にならなかったら知らなくても良い。2017年のC++入門書としては、C++17前提でいいのではないか。コンパイラC++17対応? 何の話かよくわからない。

C++が使われる場所はまだある。可搬性を重視するLinuxが(コンパイラの観点から)C++を使うことはないだろうし、システムプログラミングではGo, Rustなどが台頭してきているが、科学技術計算、ゲーム、CGなど計算能力が正義という分野では一定の地位を保っている(と、少なくとも私は感じている。要出典)。それらの分野では(中でも特にプログラミング自体は本質的でないためできれば時間をかけたくない科学技術計算分野)、多分だが、本当に「現代のC++」の入門書が求められている。

短時間で現代的なC++に習熟できる機会は用意されていないと言ってしまっていいだろう。大抵の入門書や入門コースが、新しい機能は後回しに基礎から始める。だがCやC++98から始めると、それだけで十分大変なので次へ進む時間的余裕がそもそもなくなる場合もある。あるいは、先が長すぎて習得を諦めてしまうかもしれない。そろそろ、古い時代の話は持ち出さずに、これまでのC++erが時には深手を負いながら積み上げてきた知見の上に、その屍の山を見せないままに連れて行ってもらえるような入門書をまとめる頃合いではないだろうか。

自分の立っている地盤の下にある屍の山は、そもそもあまり見たくないものだ。私だって、その全ては見ていない。見たほうが有り難みがわかるというのは当然だが、それを無理に伝えようとしてユーザーを失うのでは元も子もない。C++はそこそこ長めの歴史と様々なユーザー、様々なプロジェクトを持っているので、C++コミュニティに積極的に関わろうとするようなユーザーは遅かれ早かれその死体の山に行き当たるだろう。そして、少しばかりの黙祷を捧げた後、先へ進むだろう。今ある知見や機能の有り難みを心にしまって。それで十分ではないだろうか。

だから、そう、プログラミング初心者に向けたC++の入門書は今も意味を失っていないどころか、今こそ有意義なものなのである。追加されてきた新機能を無駄にしないためにも、そして新しいユーザー候補を泥沼に落としてしまわないためにも。


これでドンピシャな本が既にあったりしたら厳しい。そんな言うならお前が書けよと言われそうだけど技術力と時間が足りない