C++erを簡易的にレベル分けすることで初心者詐欺を減らそうという試み

# はじめに
<blockquote class="twitter-tweet" data-conversation="none" data-lang="ja"><p lang="ja" dir="ltr"><a href="https://twitter.com/takeokunn">@takeokunn</a> そういや私の昨日のツイートたどってみ、C++初心者(boost.asioが使えないとは言っていない)の人とQiitaでやりとりしてたから</p>&mdash; yumetodo-C++erだけど化学科 (@yumetodo) <a href="https://twitter.com/yumetodo/status/727309368052436992">2016年5月3日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> 
<blockquote class="twitter-tweet" data-conversation="none" data-lang="ja"><p lang="ja" dir="ltr"><a href="https://twitter.com/yumetodo">@yumetodo</a> だからC++erの初心者は初心者じゃないんだよ！！！！！！！！！！！！！<br><br>だからC++er嫌いなんだよ！！！！！！！！</p>&mdash; たけてぃ (@takeokunn) <a href="https://twitter.com/takeokunn/status/727309999102263296">2016年5月3日</a></blockquote>
<blockquote class="twitter-tweet" data-conversation="none" data-lang="ja"><p lang="ja" dir="ltr"><a href="https://twitter.com/takeokunn">@takeokunn</a> 当人も「そろそろ中級者かな」<br>と言ってた<br><br>因みに<br><br>C初心者 &lt; C++初学者 &lt; C++入門者 &lt; C++初心者 &lt; C++規格書リーディング初心者 &lt; C++中級者 &lt; C++規格書リーディング中級者 &lt; C++上級者 &lt; C++規格書クラッカー</p>&mdash; yumetodo-C++erだけど化学科 (@yumetodo) <a href="https://twitter.com/yumetodo/status/727311051117629442">2016年5月3日</a></blockquote>


こんなTwitterでのやり取りから生まれた。C++erで「初心者です」って言う人多いけど全然初心者じゃない人かなりいるよね、ということで作った。

# レベル関係

C初心者 < C++初学者 < C++入門者 < C++初心者 < C++規格書リーディング初心者 < C++中級者 < C++規格書リーディング中級者 < C++上級者 < C++規格書クラッカー

# それぞれ見ていく

あくまで上限ラインを書いているだけだからstdioがなんの略か知らなくてもC初心者よりしたというわけではない。

## C初心者

「なんか変数とかいうのがあって型とかいうのがあるらしいな。puts関数やprintf関数で標準出力に出力、fgetsで標準入力から入力を受けられるらしい」 という程度の状態、およびそれ以下である。stdioがStandard Input/Outputの略だと知っていることもある。ポインターとか配列は「なにそれ美味しいの」という状態

```c
#include <stdio.h>
int main(void)
{
    puts("arikitari na world!");
    return 0;
}
```

## C++初学者

C++初学者とは、iostreamヘッダーに標準入出力のクラス、関数群があることを知っていて、関数のオーバーロードを使ったことがある程度の状態である。

```cpp
#include <iostream>
void foo(int n){
    std::cout << "void foo(int) called( n = " << n << ")." << std::endl;
}
void foo(double n){
    std::cout << "void foo(double) called( n = " << n << ")." << std::endl;
}
int main()
{
    std::cout << "arikitari na world!" << std::endl;
    foo(3);
    foo(3.14);
}
```

## C++入門者

C++入門者とはclassの存在を知っていて書いたことがあり、また``std::string``や``std::vector``や``std::array``を操れ、algorithmヘッダーを使ったことがあり、range-based forを使える程度の状態である。なんとなくtemplateを使ってみたことがある状態を含む

```cpp
#include <iostream>
#include <array>
#include <vector>
#include <numeric>
void print(const std::vector<int>& vec)
{
	for(auto&& v : vec) std::cout << v << ',';
	std::cout << std::endl;
}
template<std::size_t N> void print(const std::array<int, N>& arr)
{
	for(auto&& a : arr) std::cout << a << ',';
	std::cout << std::endl;
}
int main()
{
	std::vector<int> v;
	v.resize(4);
	std::iota(v.begin(), v.end(), 0);
	std::array<int, 3> arr{{ 3, 1, 4 }};
	print(v);
	print(arr);
}
```

## C++初心者
C++初心者とは作りたいものを不格好でも作れ(なんでもいいんです、少しでも自分で動かしてみたいと思うものが作れれば)、また[cpprefjp](https://cpprefjp.github.io/)などを使い分からないことを調べることができ、コンパイル時定数の存在を知っていて、rvalue reference、template特殊化、簡単なSFINAEを使ったConceptのようなコードが理解でき書ける程度の状態である

分類したけどC++初心者の幅はやっぱり大きい。

なおNew Game!のねねっちはここ。NeneEngineというエンジンを自作しているたぁ驚きだね。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">ねねっち、プログラマ志望か。<a href="https://twitter.com/hashtag/newgame?src=hash">#newgame</a> <a href="https://twitter.com/hashtag/AbemaTV?src=hash">#AbemaTV</a> <a href="https://t.co/gGQfriWhtl">pic.twitter.com/gGQfriWhtl</a></p>&mdash; hiww (@hiww) <a href="https://twitter.com/hiww/status/880398895787892736">2017年6月29日</a></blockquote>

```cpp:ねねっちのコード
void DestructibleActor::Init()
{
    NeneActor::Init();
    m_currentHealth = m_maxHealth;
}

// 攻撃を食らった時のダメージ計算
void DestructibleActor::RecieveDamage(float sourceDamage)
{
    //デバフを適用
    auto resolvedDamage = sourceDamage;
    for(const auto& debuf : m_debufs)
    {
        resolvedDamage = debuf->ApplyToDamage(resolvedDamage);
    }
    m_currentHealth -= resolvedDamage;
    if(m_currentHealth <= 0.f)
    {
        m_currentHealth = 0.f;
        DestroyMe();
    }
}

//破壊せよ！
void DestructibleActor::DestroyMe()
{
    //死亡モーションがあれば再生
    //TODO: 死亡モーションを作る！
    if(m_pDeathMotion)

    //筆者注:この下は画像が見切れていて読めない
}
```

`debuf`の型は`std::shard_ptr<C>`かな？

## C++規格書リーディング初心者
C++規格書リーディング初心者とは、分からないことは規格書も参照しようと思えば本の虫などを見つつなんとかでき、またオーバーロード(ADL含む)や型推論の詳細な仕組みをそこそこ理解できている程度の状態である

## C++中級者
C++中級者とは Boost Range LibraryのOven拡張のようなoperator overloadテクニック(``operator|``を使ったメソッドチェインもどき)を自作でき、boost.asioを使え、C++11constexprの大変さを語れる状態である。また、継承を使いこなせており、なぜC++において継承だらけのプログラムをあまり見なくなったのかを自らの原体験を元に語れる状態である。

## C++規格書リーディング中級者
C++規格書リーディング中級者とは 最新規格書をすべて一度は通読し、他人のコードの誤りを規格書を参照して論理的に指摘でき、コンパイラのバグを発見できる状態である。

## C++上級者
C++上級者とはCとC++の規格書、公開されている標準化委員会の文書ほぼすべてに目を通していること、最新規格に対応しつつコンパイラのバグを回避しつつ何かしらのライブラリを作れる状態である。

## C++規格書クラッカー
C++規格書クラッカーとは、C++標準化委員会に提案が出来る程度の知識と経験を持ち、また規格書のバクを発見できる程度の状態である。つまり江添さん。岡山の陶芸家な中３女子もきっとここ

# 反響
## Twitterより
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">中級でこれとかレベル高すぎ笑う <a href="https://t.co/tF9L6ndJ0M">https://t.co/tF9L6ndJ0M</a></p>&mdash; Wreulicke (@wreulicke) <a href="https://twitter.com/wreulicke/status/727322392398172161">2016年5月3日</a></blockquote>
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">C++初心者＝C++コンパイラをフルスクラッチで作れる程度の能力</p>&mdash; 狂える中３女子ボレロ村上／陶芸C++er (@bolero_MURAKAMI) <a href="https://twitter.com/bolero_MURAKAMI/status/727326127434297348">2016年5月3日</a></blockquote>
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">僕はC++初心者～中級者ですなw これでも C++ 20年以上やってるつもりなんですけど...：C++erを簡易的にレベル分けすることで初心者詐欺を減らそうという試み by <a href="https://twitter.com/yumetodo">@yumetodo</a> on <a href="https://twitter.com/Qiita">@Qiita</a> <a href="https://t.co/q64N4vjttZ">https://t.co/q64N4vjttZ</a></p>&mdash; Takashi Kawasaki (@espresso3389) <a href="https://twitter.com/espresso3389/status/730736755150721024">2016年5月12日</a></blockquote>
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">C++erを簡易的にレベル分けすることで初心者詐欺を減らそうという試み by <a href="https://twitter.com/yumetodo">@yumetodo</a> on <a href="https://twitter.com/Qiita">@Qiita</a> <a href="https://t.co/M0l7tCqITB">https://t.co/M0l7tCqITB</a><br><br>なぜSTL以外のLib関連されるの？　これだけ納得できん</p>&mdash; GetCocoa()=nothrow (@MaverickTse) <a href="https://twitter.com/MaverickTse/status/730734162357837824">2016年5月12日</a></blockquote>
<blockquote class="twitter-tweet" data-cards="hidden" data-lang="ja"><p lang="ja" dir="ltr">つまり江添さんで笑った。確かに C++erを簡易的にレベル分けすることで初心者詐欺を減らそうという試み by <a href="https://twitter.com/yumetodo">@yumetodo</a> on <a href="https://twitter.com/Qiita">@Qiita</a> <a href="https://t.co/8l4GCKEizF">https://t.co/8l4GCKEizF</a></p>&mdash; sachin21(さっちん) (@sachin21__) <a href="https://twitter.com/sachin21__/status/730727324451135488">2016年5月12日</a></blockquote>
<blockquote class="twitter-tweet" data-cards="hidden" data-lang="ja"><p lang="ja" dir="ltr">C++erを簡易的にレベル分けすることで初心者詐欺を減らそうという試み by <a href="https://twitter.com/yumetodo">@yumetodo</a> on <a href="https://twitter.com/Qiita">@Qiita</a> <a href="https://t.co/TCNaOkKlcL">https://t.co/TCNaOkKlcL</a><br>SFINAE &lt; オーバーロードの仕組みやテンプレートの特殊化なんとなく &lt; asioの使用<br>の序列が理解できない</p>&mdash; アズなんとかさん (@as_capabl) <a href="https://twitter.com/as_capabl/status/730727189813960705">2016年5月12日</a></blockquote>
<blockquote class="twitter-tweet" data-cards="hidden" data-lang="ja"><p lang="ja" dir="ltr">C++erを簡易的にレベル分けすることで初心者詐欺を減らそうという試み by <a href="https://twitter.com/yumetodo">@yumetodo</a> on <a href="https://twitter.com/Qiita">@Qiita</a> <a href="https://t.co/rHEk1KSEm9">https://t.co/rHEk1KSEm9</a><br><br>C言語版もほしいな</p>&mdash; 笑わない数弱者 (@hirakich3141592) <a href="https://twitter.com/hirakich3141592/status/730737360355254272">2016年5月12日</a></blockquote>
<blockquote class="twitter-tweet" data-cards="hidden" data-lang="ja"><p lang="ja" dir="ltr">C# だとどうなりますか！？ / “C++erを簡易的にレベル分けすることで初心者詐欺を減らそうという試み - Qiita” <a href="https://t.co/Q4wmmSyjiQ">https://t.co/Q4wmmSyjiQ</a></p>&mdash; 田淵 義人＠エクセルソフト (@ytabuchi) <a href="https://twitter.com/ytabuchi/status/730734379761180672">2016年5月12日</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">C++初心者を名乗るためのハードル、むちゃくちゃ高いんだなあ、と思っている。C++で作りたいものがとりあえず作れないとC++初心者は名乗れないらしい。</p>&mdash; chokudai(高橋 直大) (@chokudai) <a href="https://twitter.com/chokudai/status/730726676913520642">2016年5月12日</a></blockquote>
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">C++erを簡易的にレベル分けすることで初心者詐欺を減らそうという試み by <a href="https://twitter.com/yumetodo">@yumetodo</a> on <a href="https://twitter.com/Qiita">@Qiita</a> <a href="https://t.co/Vl9QUTkXv0">https://t.co/Vl9QUTkXv0</a><br><br>C初心者です</p>&mdash; たけてぃ (@takeokunn) <a href="https://twitter.com/takeokunn/status/783332186615197701">2016年10月4日</a></blockquote>
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr"><a href="https://twitter.com/yumetodo">@yumetodo</a> <a href="https://twitter.com/Qiita">@Qiita</a> そもそもプログラマーの初心者詐欺とはなんやねん。</p>&mdash; なぞのひと(N氏)＠雑談 (@nz_hito_pc__93) <a href="https://twitter.com/nz_hito_pc__93/status/783332329993363461">2016年10月4日</a></blockquote>
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">初心者詐欺はするものだと思う <a href="https://t.co/WiEESTtv1e">https://t.co/WiEESTtv1e</a></p>&mdash; かぐちょ「神御田」@アイマス「神御田Ｐ」 (@kagucho_kamioda) <a href="https://twitter.com/kagucho_kamioda/status/783347184125120513">2016年10月4日</a></blockquote>

## はてなブックマークより
http://b.hatena.ne.jp/entry/qiita.com/yumetodo/items/a843bd542106215bbc84

抜き出すとまさかりが飛んできそうなので各自見てください。

# まとめ

異論はたくさんあると思うけど、C++初心者怖い状態がなくなればいいなと思います。
<blockquote class="twitter-tweet" data-conversation="none" data-lang="ja"><p lang="ja" dir="ltr"><a href="https://twitter.com/yumetodo">@yumetodo</a> だからC++erの初心者は初心者じゃないんだよ！！！！！！！！！！！！！<br><br>だからC++er嫌いなんだよ！！！！！！！！</p>&mdash; たけてぃ (@takeokunn) <a href="https://twitter.com/takeokunn/status/727309999102263296">2016年5月3日</a></blockquote>


え？私？多分C++規格書リーディング初心者だと思う。

# 追記

どうも``C++規格書リーディング初心者``は長過ぎるようで「初心者ってことでいいよね？」という声が聴こえる。・・・いやダメだろ。

なんでboost.asioだけ出てきているかというと、あれを使えるということはcallback地獄への対処のためにいろいろ知っていないといけないので、という意味で上げました。~~断じて[C++初心者(boost.asioが使えないとは言っていない)の人](http://www.slideshare.net/chihayatakatuki/boost-asio)を弾くためではない~~

対抗記事とか他言語版記事とか出ないかな(ﾁﾗｯ

このレベル分けで「20年プログラマ」やってるけど(ryが発生しているのは、あくまで**C++の言語仕様**に着目してレベル分けしているからで、「計算機科学」「ツール・文化」「ドメイン知識」とかとかの分野別に分けていないから。だから**簡易的**という言葉で逃げてたんですね。

あ、MFCとかC++/CLIはお帰りください。

なんか誤解を与えているようなので追記しますが、C初心者<C++初学者となっているのは、C++の下位言語としてCがあると言っているわけではなく、C++をやるのにCの知識は多少必要だと言いたいだけです。Cを使いこなせることとC++を使いこなせることは全く別方向の話ですので誤解のないように。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">すごいエンジニアの謙遜発言に「魔界では」をつけるとしっくりくる<br><br>「こんなの魔界ではふつうだよ」<br>「俺なんて魔界では大したことないよ」<br>「魔界では素人の質問なんですがいいですか」</p>&mdash; sat (@satoru_takeuchi) <a href="https://twitter.com/satoru_takeuchi/status/808089090285416448">2016年12月11日</a></blockquote>
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">魔界では初心者の皆さん</p>&mdash; たけてぃ (@takeokunn) <a href="https://twitter.com/takeokunn/status/808686321803767808">2016年12月13日</a></blockquote>

なるほど・・・？

冒頭で触れた、C++初心者(boost.asioが使えないとは言っていない)の人が
[C++ステップアップにむけて 段階を作ってみた - Qiita](http://qiita.com/YukiMiyatake/items/bb16475278ccd93de312)
なんていう記事を書いたようだ。。なるほど、面白い。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">C中級者「やったぞ！長年の修行の末、遂にポインタを理解したぞ！」<br>strict aliasing rules「フハハハ！引っかかったな！そいつは影武者だ！」</p>&mdash; takl (@takl) <a href="https://twitter.com/takl/status/958342684850102272?ref_src=twsrc%5Etfw">January 30, 2018</a></blockquote> 

C言語・・・

# この記事を書いた意図について

ようやくこの記事のviewの伸びも収まってきたのと、[某所](https://teratail.com/questions/69597)で誤解を受けていたのでこっちにも意図を書いておきますか。

この記事は、現代のC++があまりにも難解になっているのでおおよそ仕様をすべて把握し、C++の言語としての特性を、コーディングを実際にするユーザーがうまく利用して「楽をする」ことができなくなっているな、と思ったので、記事冒頭のツイートをきっかけに書いたものです。

> http://b.hatena.ne.jp/entry/287284443/comment/q7z
> q7zのコメント 2016/05/13 23:11
> こういう言動がホントに初心者に迷惑かけてることに気づいてないんだろうな。敬遠されるような事をして悦に入ってるだけ。

というコメントがはてなブックマークについていますが、ある意味狙い通りです。
よっぽど記事中に引用しようかと思いましたが、無駄にview数が伸びてたので炎上しそうで、「抜き出すとまさかりが飛んできそうなので各自見てください。」と書くにとどめましたが、
このコメントを見てくれた人はどのくらいいたんだろうか。

だって、現代見かけるC++のコードを書くために覚えることがあまりにも多すぎるじゃないですか。
実際のところ私は継承もオーバーロードも理解しきれていませんし。

で、本来、プログラミング言語そのものを相当知らないと水準のコードが書けないというのはおかしいはずです。たかが道具なのに。
ところがC++の場合、言語仕様を半ば悪用したトリッキーなコードがデファクトスタンダードになっているがために、言語そのものを相当勉強しないといけない。
せめてRustみたいにコンパイルエラーがわかりやすければまだ良かったかもしれないがそれすらないからユーザーはライブラリの実装を読んで理解しないといけない(Conceptはよ)。

少なくとも私は、みなさんと違ってC++11から入門した人間ですが、当時江添さんの本の虫の記事を必死に読み漁り(もちろんググりながらなのでfaithandbraveさんはじめ多くの人の記事もよみました)、
やっとこのわけわかんないコートはどうしてこれ以上わかりやすくかけないのか、おぼろげに理解できるようになるまで約半年、本当に大変でした。なんせC++にはまともな入門本すらないですからね。

現状のC++の存続意義は過去の資産の活用と速度追求の2点に絞られると思っています。速度を追求しないのであればほかにいくらでも適当な、かんたんな言語はあるはずです(C#とかRustとかGo？)。
逆に言えば速度追求のためならなんでも許される、そういう空気を私は感じています。これがますますC++を難解にさせている原因かもしれません。

[C++11]lambda、[C++11]ravlue reference、[C++14]constexpr、[C++17]template classの実引数推定や[はよこい]Conceptなど改善がないわけではないですが、
少なくとも私は今後輩にC++を勉強してみたら？とは言えません。実際JavaScriptとRustを勧めてます。
今のC++界隈の状況で、C++入門したら、無駄に時間が消し飛んで振り回されるだけです。まじで今のC++おかしいんじゃねーの？私はC++が好きだから使い続けるけど。

まあしかし、この記事View数伸びすぎてませんかね？
なんでああいうランク分けがC++において**のみ**成立して、またこれだけview数があって(さっき確認したら23739views!?)

>対抗記事とか他言語版記事とか出ないかな(ﾁﾗｯ

と煽ってなお他の言語版の記事が出ない理由は何なのかまでちゃんと伝わっているとは思えないし。

まあせめてあの記事を見てC++から離れた初心者がいれば、すこしは意味があったのかな、上述の内容が伝わらなくても。この記事書いたときはそこまで思ってなかったけど。

せめてC++17に対応したまともな入門書が出てくれないですかね？一時期本気で書こうかと思ったけど、私の大学の単位が消し飛ぶので自重しています。
江添さんが
https://github.com/EzoeRyou/cpp17book
を書き始めているけど、これは入門書ではないし。

追記: 江添さんが入門書を書いていますね
https://github.com/EzoeRyou/cpp-intro

# 追記: 2021-04

新卒でこの春入社した会社でどうやら全社にこの記事が通知されたらしく震えています

# License

[CC BY 4.0](https://creativecommons.org/licenses/by/4.0/deed.ja)

<a href="https://commons.wikimedia.org/wiki/File:CC-BY_icon.svg#/media/File:CC-BY_icon.svg"><img src="https://upload.wikimedia.org/wikipedia/commons/thumb/1/16/CC-BY_icon.svg/1200px-CC-BY_icon.svg.png" alt="CC-BY icon.svg" width="88px"></a>