私は10年ほど前にC++の仕様を隅から隅まで覚えたことがあるが、それから10年、全く触っていない。Cは時々接するのでANSI Cの仕様はまだ結構覚えているが、C++の仕様は全般的にうろ覚えだ。
そんな状態で、久々にC++の仕様を眺めていると、すっかり忘れていることがいくつもあったので、ここに記す。
(1) 構造体内の構造体定義の参照
struct Outer{ struct Inner{ int i; } j; }というコードのInnerを参照する場合、Cだと
struct Inner i;とできるが、C++だと
struct Outer::Inner i;としないといけない。
(2)int値のenum型への変換
Cでは
enum Color {RED=1, GREEN, BLUE}; enum Color c; c = 1;ができるが、C++ではできない。
c = Color(1); c = (Color)1;のようにする必要がある。
蛇足だが、Cで"c = Color(1);"とすると、コンパイルエラーとはならず、Color()という関数が無いというリンクエラーになる。
(3)template文はクラス定義以外にも使える
template<class T> T square(T x) { T y; y = x * x; return y; }のような関数定義もできる。
ひょっとしてtemplateをクラス定義にしか使えないと思い込んでいる人は少数だろうか。
(4)通常型引数と参照型引数の多重定義
C++では引数の型を変えて同じ名前の関数を多重定義できるが、
void foo(int i) {} void foo(int &i) {}の2つを同時に定義することはできない。
よく考えると、これらの関数を呼び分けられないので当然とも思える。
同様に
void foo(int i) {} void foo(const int &i) {}の組み合わせも不可だが、
void foo(int &i) {} void foo(const int &i) {}の2つは同時に定義できる。
なお、g++では重複定義自体はエラーにならず、呼び出し文にてコンパイルエラーとなった。
KaBA
C++の複雑な仕様の中をよく覚えてますね!
まねできないっす。。。
最近はCさえ忘れてきました。。。
もっぱらjavaで、ぬるま湯につかってます。
ynomura
いえいえ、すっかり忘れてたってことでして…
どうでもいいですが、MovableTypeでソースコードを貼り付けるの難しいですね。preタグを使うとやたら行間が空くし、preタグを使わずにインデントを表示しようとしたら全角スペース使うくらいしかないし、そうするとcopy&pasteでコンパイルエラーになるソースになるし…
preタグ中でも"<"や">"が消えてしまうのは盲点でした。
KaBA
C++ってホント難しいですね。
私は多重継承+friend関数で脱落しました。
でも、いろいろと応用が効きそうですね。
ynomuraさんの記事をみると。
あとは、interfaceが使えるといいのですけれど。今はどうなんですか?
演算子オーバーロードは初心者の頃、惹かれました。
私もHTMLはとっくの昔に忘れてしまいました。
pタグか、quote(?)タグはどうですか?
あ、インデントか。。。
ネストもできなかったでしたっけ?
<>は要注意っすね。
ynomura
今回実は大学時代に取ったC++の入門書のコピーを捨てる前に読み返してたんですが、読む前は、friendって何で要るんだったっけ?という状態でした。
特に演算子のオーバーライドをする時は重要のようです。
C++はJavaと違って多重継承ができるので、インターフェースは昔から抽象クラス(仮想クラス)として記述することになってます。
みたいに。HTMLでのインデントについては、結局HTML 4.01の仕様を調べたんですが、下記URLの9.1節に、preタグ以外では連続した空白は単語の区切りと解釈する、と明記されています。しかもTabは強く非推奨(9.3.4節)だそうで。
http://www.w3.org/TR/html401/struct/text.html
ネストは可能なんですが、<pre>を使った途端に行間が空いてしまいます。使ってるstylesheetのせいかも知れませんが。
というか、codeタグ(9.2節)を使ってもインデントが無視されてしまう仕様なのが、実に不思議です。
ynomura
preタグを使うとやたら行間が空くのは、stylesheetのせいではなく、エントリーに「改行を変換する」(Convert Line Breaks)設定をした場合のMovableTypeの仕様だったようで、<pre>~</pre>の間の改行にも<br />が追加されて改行が2重になってたのが原因でした。
<pre>~</pre>等の間の改行は変換しないプラグインもあるようですが、<pre>や<table>を使うエントリーは「改行を変換する」設定にしない方が良さそうです。