出張で飛行機に乗っている間、久しぶりにC++の本を開いて、自分の知らないC++の使い方について調査していたのだが、C++11の新機能として、いろいろと簡単に書き換えられそうなものがある。
Effective Modern C++ ―C++11/14プログラムを進化させる42項目
- 作者: Scott Meyers,千住治郎
- 出版社/メーカー: オライリージャパン
- 発売日: 2015/09/18
- メディア: 大型本
- この商品を含むブログ (6件) を見る
自作ISSのコードについては、C++11の対応を進めてきたつもりだ。例えば、スマートポインタの導入や、autoを使ったSTLコンテナの探索を記述簡略化などを進めてきた。
今回導入するのは、typedefの代わりにusingを使い、enumの代わりにenum classを導入するということだ。 どちらも、現状のISSにおいて導入しても、明確な利点が現れるわけではないのだが、今後のために導入しておこう。
C++11のusingについて
C++11のusingは、typedefに置き換わるものらしい。非常に簡単なケースでいうと、以下のような書きかえを行った。
-typedef std::vector<FunctionInfo *> FunctionTable; +using FunctionTable = std::vector<FunctionInfo *>;
このようにする。これで、typedefを置き換えることができる。 これだけだと、明確な利点が存在していないように見えるが、usingを使うことにより、テンプレート化をすることが利点だ。
template<typename T> using MyAllocList = std::list<T, MyAlloc<T>>; MyAllocList<Widget> lw;
C++11のenum classについて
これも、enumに取って代わるものだ。非常に簡単なケースでいうと、以下のような書き換えを行った。
enum class PrivMode { PrivUser = 0, PrivSupervisor = 1, PrivHypervisor = 2, PrivMachine = 3 }; ... switch (curr_priv) { case PrivMode::PrivUser : { ... case PrivMode::PrivSupervisor : { ... case PrivMode::PrivHypervisor : { ...
これにより、enumで定義したものはクラスとして定義され、明確の型として宣言されることになる。したがって、これらの定数を数値として扱うためには、それらを明示的に変換する必要がある。
enum class ExceptCode { Except_InstAddrMisalign = 0, Except_InstAccessFault = 1, Except_IllegalInst = 2, Except_Breakpoint = 3, Except_LoadAddrMisalign = 4, ... if (code == ExceptCode::Except_InstAddrMisalign) { epc = GetPreviousPC (); ... SetPrivMode (PrivMode::PrivMachine); CSRWrite (SYSREG_ADDR_MEPC, epc); CSRWrite (SYSREG_ADDR_MCAUSE, static_cast<Word_t>(code)); SetPC (0x00000100); SetJumped (true);
codeは、ExceptCode型として定義されているので、Word_tに変換した上でレジスタへの書き込みを実行する、という訳だ。 いちおう、これらの書き換えを行って、リグレッションテストを行った。問題なしだ。