<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title>zakio.net</title>
    <link rel="alternate" type="text/html" href="http://zakio.net/blog/" />
    <link rel="self" type="application/atom+xml" href="http://zakio.net/blog/atom.xml" />
    <id>tag:zakio.net,2009-02-15:/blog//1</id>
    <updated>2010-03-16T00:57:01Z</updated>
    <subtitle>端くれエンジニアの憂鬱</subtitle>
    <generator uri="http://www.sixapart.com/movabletype/" version="4.23-ja">Movable Type Pro</generator>

<entry>
    <title>static_cast をいい加減な気持ちで適当に付けないと決めた日</title>
    <link rel="alternate" type="text/html" href="http://zakio.net/blog/2010/03/15-213053.html" />
    <id>tag:zakio.net,2010:/blog//1.17</id>

    <published>2010-03-15T12:30:53Z</published>
    <updated>2010-03-16T00:57:01Z</updated>

    <summary>
        <![CDATA[<p>
最近、些細なことに気付く程度には余裕が出てきたのだろう。ふと自分のコードを見直してみると、static_cast を単なる「警告除け」や「コンパイルエラー除け」として、あやふやな理解のまま使っていることに気付いた。どうやら私は、static_cast をなんとなく「それ以外の cast」といったような感覚で使っているようだ。「それ」とはもちろん、標準で用意されている static_cast 以外の cast、dynamic_cast, const_cast, reinterpret_cast の3つのこと。これらの cast は役割が結構はっきりしているので、それぞれ、安全なダウンキャスト用、const 外し用、強制置き換え用として（もちろん必要に迫られて）迷うことなく使っている。ところが static_cast だけは、それ以外の状況で警告（あるいはコンパイルエラー）が出た時に仕方なく付けているというわけだ。そこに明確な理由も意思もない。単なるコンパイラのご機嫌取りだ。情けない。
</p>

<p>
このままでは、新人君に「先輩、ここの static_cast にはどのような効果があるのですか？」と聞かれても、「あ、それ？ なんとなく、コンパイラが文句言ってたし」としか答えられないし、先輩に「ここで static_cast はないだろう」と言われても「あ、はい、そうですね。コンパイルエラー出ちゃったんでなんとなく付けちゃいました」となんとも間抜けな回答しかできないことになる。このままではマズイ。
</p>

<p>
前置きが長くなってしまったが、要は「static_cast について自分なりにまとめましたよ」という話だ。
</p>]]>
    </summary>
    <author>
        <name>zakio</name>
        <uri>http://zakio.net/</uri>
    </author>
    
        <category term="C++" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="c" label="C++" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="static_cast" label="static_cast" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="ja" xml:base="http://zakio.net/blog/">
        <![CDATA[<p>
最近、些細なことに気付く程度には余裕が出てきたのだろう。ふと自分のコードを見直してみると、static_cast を単なる「警告除け」や「コンパイルエラー除け」として、あやふやな理解のまま使っていることに気付いた。どうやら私は、static_cast をなんとなく「それ以外の cast」といったような感覚で使っているようだ。「それ」とはもちろん、標準で用意されている static_cast 以外の cast、dynamic_cast, const_cast, reinterpret_cast の3つのこと。これらの cast は役割が結構はっきりしているので、それぞれ、安全なダウンキャスト用、const 外し用、強制置き換え用として（もちろん必要に迫られて）迷うことなく使っている。ところが static_cast だけは、それ以外の状況で警告（あるいはコンパイルエラー）が出た時に仕方なく付けているというわけだ。そこに明確な理由も意思もない。単なるコンパイラのご機嫌取りだ。情けない。
</p>

<p>
このままでは、新人君に「先輩、ここの static_cast にはどのような効果があるのですか？」と聞かれても、「あ、それ？ なんとなく、コンパイラが文句言ってたし」としか答えられないし、先輩に「ここで static_cast はないだろう」と言われても「あ、はい、そうですね。コンパイルエラー出ちゃったんでなんとなく付けちゃいました」となんとも間抜けな回答しかできないことになる。このままではマズイ。
</p>

<p>
前置きが長くなってしまったが、要は「static_cast について自分なりにまとめましたよ」という話だ。
</p>]]>
        <![CDATA[<p>
こういう話は一時ソースから辿るのがベスト。ISO IEC 14882-2003, 5.2.9 Static cast [expr.static.cast] に、static_cast について「これでもか」とばかりに1ページほど記述されているので、この際だから順番に追っていくことにしよう。
</p>

<blockquote>
<p>The result of the expression static_cast&lt;T&gt;(v) is the result of converting the expression v to type T. If T is a reference type, the result is an lvalue; otherwise, the result is an rvalue. Types shall not be defined in a static_cast. The static_cast operator shall not cast away constness (5.2.11).</p><br />
<p>static_cast&lt;T&gt;(v) と書くと、v を T 型に変換した結果が得られる。T が参照型なら結果は lvalue, そうじゃないなら rvalue だ。static_cast 内で型を定義するのはダメ。あと、const は外せないよ。</p><br />
<p><cite>ISO IEC 14882-2003, 5.2.9 Static cast - 1</cite></p>
</blockquote>

<p>
ここでは static_cast が型を変換するという事と、const を外せない事を言っている。まだまだ序の口。
</p>

<blockquote>
<p>An expression e can be explicitly converted to a type T using a static_cast of the form static_cast&lt;T&gt;(e) if the declaration "T t(e);" is well-formed, for some invented temporary variable t (8.5). The effect of such an explicit conversion is the same as performing the declaration and initialization and then using the temporary variable as the result of the conversion. The result is an lvalue if T is a reference type (8.3.2), and an rvalue otherwise. The expression e is used as an lvalue if and only if the initialization uses it as an lvalue.</p><br />
<p>もし、T t(e) と書けるなら、static_cast&lt;T&gt;(e) は合法だ。static_cast の結果、t に相当する一時オブジェクト（T が参照型なら lvalue, それ以外なら rvalue）が作られるからね。一時オブジェクトの生成時に e が lvalue として扱われることもあるけど、まぁそれはコンストラクタ次第かな。</p><br />
<p><cite>ISO IEC 14882-2003, 5.2.9 Static cast - 2</cite></p>
</blockquote>

<p>
ちょっと端折りすぎかも知れないが、ここでは static_cast がコンストラクタを呼ぶことと等価であると言っている......と思う。コンストラクタで構築できるものは static_cast でも変換可能。これもまぁ、当たり前っちゃぁ当たり前。
</p>

<blockquote>
<p>Otherwise, the static_cast shall perform one of the conversions listed below. No other conversion shall be performed explicitly using a static_cast.</p><br />
<p>それ以外の場合、static_cast は以下の変換を行うよ。static_cast の機能はこれだけだからね。</p><br />
<p><cite>ISO IEC 14882-2003, 5.2.9 Static cast - 3</cite></p>
</blockquote>

<p>
よし、ココからが本番だ。
</p>

<blockquote>
<p>Any expression can be explicitly converted to type "cv void." The expression value is discarded. [Note: however, if the value is in a temporary variable (12.2), the destructor for that variable is not executed until the usual time, and the value of the variable is preserved for the purpose of executing the destructor. ] The lvalue-to-rvalue (4.1), array-to-pointer (4.2), and function-to-pointer (4.3) standard conversions are not applied to the expression.</p><br />
<p>どんな型でも void にできる。もちろん、値は無くなっちゃうけどね。（あ、無くなっちゃうとは言っても、一時オブジェクトのデストラクタが呼ばれるのは通常のタイミングと同じ。つまり一時オブジェクトの寿命が尽きた時なので注意。）<br />
あと、ここでは lvalue-to-rvalue, array-to-pointer, function-to-pointer の標準変換は適用されないよ。</p><br />
<p><cite>ISO IEC 14882-2003, 5.2.9 Static cast - 4</cite></p>
</blockquote>

<p>
つまりは、static_cast&lt;void&gt;(何でもOK) は合法ということ。これ自体の使い道は思いつかないが（template がらみで役立つかも？）、こういう重箱の隅までキッチリ書かれているところなどは、まさに規格書といったところか。
</p>

<blockquote>
<p>An lvalue of type "cv1 B", where B is a class type, can be cast to type "reference to cv2 D", where D is a class derived (clause 10) from B, if a valid standard conversion from "pointer to D" to "pointer to B" exists (4.10), cv2 is the same cv-qualification as, or greater cv-qualification than, cv1, and B is not a virtual base class of D. The result is an lvalue of type "cv2 D." If the lvalue of type "cv1 B" is actually a sub-object of an object of type D, the lvalue refers to the enclosing object of type D. Otherwise, the result of the cast is undefined.<br />
[Example:<br />
&nbsp;&nbsp;	struct B {};<br />
&nbsp;&nbsp;	struct D : public B {};<br />
&nbsp;&nbsp;	D d;<br />
&nbsp;&nbsp;	B &amp;br = d;<br />
&nbsp;&nbsp;	static_cast&lt;D&amp;&gt;(br); // produces lvalue to the original d object<br />
-end example]</p><br />
<p>クラス B から派生したクラス D があった時、D* を B* に変換できるなら、static_cast は B 型の lvalue を D への参照型に変換できる。ただし、B が仮想基底クラスでない場合に限るよ。もちろん、B が本当に D を指していないなら結果は未定義だからね。<br />
（cv については自明なのであえて省略。）</p><br />
<p><cite>ISO IEC 14882-2003, 5.2.9 Static cast - 5</cite></p>
</blockquote>

<p>
ここは1つのポイント。親子関係にあるクラス間の変換を説明しているが、アップキャストではなくダウンキャストについて述べている点に注意しよう。つまり、ここでは static_cast によって安全でないダウンキャストが可能であると言っている。
</p>

<p>
これで、先ほどの「ここで static_cast はないだろう」という先輩に対して、「いや、ここは確実に D を指していることが分かっているので、dynamic_cast よりも効率の良い static_cast を使っているわけですよ」と反論できるようになった。（その後、そもそも D と分かっているという事は云々......といった感じで議論が続くと思われるが、static_cast の範疇を越えるのでこれ以上は言及しない。）
</p>

<blockquote>
<p>The inverse of any standard conversion sequence (clause 4), other than the lvalue-to-rvalue (4.1), array-to-pointer<br />
(4.2), function-to-pointer (4.3), and boolean (4.12) conversions, can be performed explicitly using static_cast. The lvalue-to-rvalue (4.1), array-to-pointer (4.2), and function-to-pointer (4.3) conversions are applied to the operand. Such a static_cast is subject to the restriction that the explicit conversion does not cast away constness (5.2.11), and the following additional rules for specific cases:</p><br />
<p>lvalue-to-rvalue, array-to-pointer, function-to-pointer, boolean conversion 以外の標準変換は、static_cast で逆変換できる。この時の static_cast は const を外せないこと以外に以下の特別ルールが適用される。</p><br />
<p><cite>ISO IEC 14882-2003, 5.2.9 Static cast - 6</cite></p>
</blockquote>

<p>
標準変換については4章でがっつり述べられているが、整数の格上げやら浮動小数と整数の変換やら、警告が出そうな変換の類がこれに相当する。ここで重要なのは「逆変換」という部分。私が多用するのは「暗黙の変換によって値が範囲外になってしまうかもよ」とか「signed と unsigned が食い違っているよ」といった警告に対して「はい、分かってやってるんで」と意思表示をするための static_cast だが、ここで述べられているのは、4章の標準変換に含まれていない逆変換も static_cast によって可能になるという話なので、警告除けとは別次元の話。<br />
つまり、逆向きが許されていない標準変換（つまり逆変換がエラーとなる変換）であっても、static_cast を使えば逆変換が可能になるという話だ。
</p>

<p>
どうやらこの辺りを理解すれば「警告除け」と「必然的な static_cast」の違いについて後輩に説明できるようになりそうな気がしてきた。はやる気持ちを抑え、とりあえず、以降の特別ルールについて見ていくことにしよう。
</p>

<blockquote>
<p>A value of integral or enumeration type can be explicitly converted to an enumeration type. The value is unchanged if the original value is within the range of the enumeration values (7.2). Otherwise, the resulting enumeration value is unspecified.</p><br />
<p>整数や enum は enum に変換できる。当然だけど enum の範囲外の値を enum に cast すると、変換後の値は不定になるよ。</p><br />
<p><cite>ISO IEC 14882-2003, 5.2.9 Static cast - 7</cite></p>
</blockquote>

<p>
これは逆向きが許されていない標準変換、enum → int に関する特別ルール。static_cast を使えば enum → int の逆向きである int → enum が可能になるが、enum の範囲外の値を enum に変換すると不定になるという（当たり前の）特別ルールを設けている。
</p>

<blockquote>
<p>An rvalue of type "pointer to cv1 B", where B is a class type, can be converted to an rvalue of type "pointer to cv2 D", where D is a class derived (clause 10) from B, if a valid standard conversion from "pointer to D"to "pointer to B" exists (4.10), cv2 is the same cv-qualification as, or greater cv-qualification than, cv1, and B is not a virtual base class of D. The null pointer value (4.10) is converted to the null pointer value of the destination type. If the rvalue of type "pointer to cv1 B" points to a B that is actually a sub-object of an object of type D, the resulting pointer points to the enclosing object of type D. Otherwise, the result of the cast is undefined.</p><br />
<p>クラス B から派生したクラス D があって、D* を B* に変換できる（アップキャストが許されている）なら、static_cast で B* を D* に変換できる（ただし、B が仮想基底クラスの場合を除く）。この時、null ポインタは null ポインタに変換されることが保証されているからね。あと、何度も言うようだけど、B へのポインタが実は D を指していないのに static_cast で D* に変換してしまうと、何が起こってもおかしくないから注意してね。</p><br />
<p><cite>ISO IEC 14882-2003, 5.2.9 Static cast - 8</cite></p>
</blockquote>

<p>
これは逆向きが許されていない標準変換、アップキャストに関する特別ルール。アップキャストの逆変換であるダウンキャストもまた static_cast で可能となるが、仮想基底クラスからのダウンキャストは無理な点と、dynamic_cast で失敗するようなケースで使うと未定義となることが述べられている。
</p>

<p>
ところで、「D* を B* に変換できる（アップキャストが許されている）なら」とわざわざ述べているが、そうならない場合とはどんな場合なのだろう。これは public でない継承を考えれば納得できる。例えば以下の通り。
</p>

<pre><code>
<span class="synType">class</span> B {
};

<span class="synType">class</span> D: <span class="synStatement">private</span> B {
};

<span class="synType">void</span> Test()
{
  D d;
  B* pb = &amp;d; <span class="synComment">// エラー！ D* から B* への変換は許されていない</span>
}

</code></pre>

<p>
アップキャストできないという事は、ダウンキャストの対象となるポインタそのものが得られないという事なので、この場合にダウンキャストできないというのは容易に理解できるだろう。
</p>

<blockquote>
<p>An rvalue of type "pointer to member of D of type cv1 T" can be converted to an rvalue of type "pointer to member of B of type cv2 T", where B is a base class (clause 10) of D, if a valid standard conversion from "pointer to member of B of type T" to "pointer to member of D of type T" exists (4.11), and cv2 is the same cv-qualification as, or greater cv-qualification than, cv1.63) The null member pointer value (4.11) is converted to the null member pointer value of the destination type. If class B contains the original member, or is a base or derived class of the class containing the original member, the resulting pointer to member points to the original member. Otherwise, the result of the cast is undefined. [Note: although class B need not contain the original member, the dynamic type of the object on which the pointer to member is dereferenced must contain the original member; see 5.5. ]</p><br />
<p>static_cast を使えば D のメンバへのポインタを B のメンバへのポインタに変換できる。クラスの関係や逆変換が存在することといった条件や、null ポインタ云々、変換先が存在しない場合に未定義となる点は全てクラスの場合と同じ。</p><br />
<p><cite>ISO IEC 14882-2003, 5.2.9 Static cast - 9</cite></p>
</blockquote>

<p>
メンバポインタ！ これは幸いなことに（決して短くはないプログラマ人生の中で）まだ1回しか使った事がない機能だったりするのだが、言われてみれば確かにこいつもクラスへのポインタと同じような関係が成り立つはず。練習がてらにサンプルを作ってみたが、如何せん経験が浅いのでここで述べられている事を説明し切れているかどうかは自信なし。
</p>

<pre><code>
<span class="synType">class</span> B {
<span class="synStatement">public</span>:
  <span class="synType">virtual</span> <span class="synType">void</span> Func() { std::cout &lt;&lt; <span class="synConstant">&quot;B::Func() called&quot;</span> &lt;&lt; std::endl; }
};

<span class="synType">class</span> D: <span class="synStatement">public</span> B {
<span class="synStatement">public</span>:
  <span class="synType">virtual</span> <span class="synType">void</span> Func() { std::cout &lt;&lt; <span class="synConstant">&quot;D::Func() called&quot;</span> &lt;&lt; std::endl; }
};

<span class="synType">void</span> Test()
{
  B b;
  D d;
  <span class="synType">void</span> (B::* mpb)() = &amp;B::Func; <span class="synComment">// B のメンバ関数へのポインタ</span>
  <span class="synType">void</span> (D::* mpd)() = &amp;D::Func; <span class="synComment">// D のメンバ関数へのポインタ</span>
  (b.*mpb)(); <span class="synComment">// メンバポインタを介した関数呼び出し（B::Func が呼ばれる）</span>
  <span class="synComment">//(b.*mpd)(); // エラー! B のオブジェクトに D::* を使おうとしている</span>
  (d.*mpb)(); <span class="synComment">// メンバポインタを介した関数呼び出し（B::Func は仮想関数なので D::Func が呼ばれる）</span>
  (d.*mpd)(); <span class="synComment">// メンバポインタを介した関数呼び出し（D::Func が呼ばれる）</span>

  <span class="synComment">//void (B::* dtob)() = mpd; // エラー! D::* から B::* への暗黙の変換は許されていない</span>
  <span class="synType">void</span> (B::* dtob)() = <span class="synStatement">static_cast</span>&lt;<span class="synType">void</span> (B::*)()&gt;(mpd); <span class="synComment">// でも static_cast を使えば変換可能</span>
  <span class="synType">void</span> (D::* btod)() = mpb; <span class="synComment">// B::* から D::* への変換は OK</span>
  (b.*dtob)(); <span class="synComment">// B::Func が呼ばれる（これが original pointer 云々の部分で言いたいことだと思う）</span>
  <span class="synComment">//(b.*btod)(); // エラー! B のオブジェクトに D::* を使おうとしている</span>
  (d.*dtob)(); <span class="synComment">// D::Func が呼ばれる</span>
  (d.*btod)(); <span class="synComment">// D::Func が呼ばれる</span>
}

</code></pre>

<p>
メンバポインタの場合はクラスへのポインタとは逆で、子クラスから親クラスへの変換が許されていない。これは親クラスが子クラスのメンバを持っているとは限らないからと考えると理解しやすいと思う。
</p>

<blockquote>
<p>An rvalue of type "pointer to cv1 void" can be converted to an rvalue of type "pointer to cv2 T," where T is an object type and cv2 is the same cv-qualification as, or greater cv-qualification than, cv1. A value of type pointer to object converted to "pointer to cv void" and back to the original pointer type will have its original value.</p><br />
<p>static_cast を使えば void* を T* に変換できる。当然だけど、その void* が元々は T* であった場合に限るよ。</p><br />
<p><cite>ISO IEC 14882-2003, 5.2.9 Static cast - 10</cite></p>
</blockquote>

<p>
これも T* → void* の逆バージョン。標準変換では許されていないが、static_cast によって変換できるようになる。
</p>

<p>
static_cast に関する C++ の仕様は以上だ。私の中で理解があいまいだったのは、標準変換の逆変換と警告除けがごっちゃになっていた部分だった。標準変換自体は static_cast は不要。コンパイラは cast によって値が失われるかも知れないよと警告しているに過ぎない。当たり前と言えば当たり前だが、コンパイラが文句を言ったら static_cast を付けるという情けない対応で何とかなっていたため、完全に思考停止状態だった。本当にエラーになるような状況でも警告と同じように static_cast を付けるだけだったので、頭の中でこれらを区別しきれていなかったというわけだ。
</p>

<p>
以上を踏まえ、これからは static_cast を「それ以外の cast」ではなく、以下のような場合に使う cast として、意識的に区別しながら使ってみようと思う。
</p>

<ol>
	<li>安全でないダウンキャスト用の cast</li>
	<li>int → enum 用の cast</li>
	<li>void* → T* 用の cast</li>
	<li>警告除けの意思表示</li>
</ol>

<p>
1は元々区別して扱っていた（し、そもそも滅多に使わない）ので、結局のところ 2, 3 と 4 を区別するようになったところが進歩したところか。まぁ、コンパイラが文句を言った後で static_cast を付けるという流れはしばらく変わらないと思うが、その時に機械的に付けるのか、それとも意味を考えながら付けるのかには大きな差がある、と信じたい。<br />

</p>]]>
    </content>
</entry>

<entry>
    <title>法則に違反したっていいじゃない</title>
    <link rel="alternate" type="text/html" href="http://zakio.net/blog/2009/07/22-111055.html" />
    <id>tag:zakio.net,2009:/blog//1.16</id>

    <published>2009-07-22T02:10:55Z</published>
    <updated>2009-07-22T02:12:14Z</updated>

    <summary>
        <![CDATA[<p>
オブジェクト指向プログラミングにおける有名な法則の一つに<a href="http://ja.wikipedia.org/wiki/%E3%83%87%E3%83%A1%E3%83%86%E3%83%AB%E3%81%AE%E6%B3%95%E5%89%87">デメテルの法則</a> (Law of Demeter, LoD) というものがある。これは、簡単に言えば「戻り値として返されたオブジェクトのメソッドを呼び出してはいけない」という法則であり、例えば次のようなコードを書くと、「それ、デメテルの法則に違反しているよ」などと言われたりするので注意が必要だ。
</p>

<pre><code>
<span class="synType">int</span> id = projects.Find(projectName).GetID(); <span class="synComment">// プロジェクト名から ID を取得</span>

</code></pre>

<p>
そして、このコードをデメテルの法則に違反しないように書き換えると、次のようになる。
</p>

<pre><code>
<span class="synType">int</span> id = projects.GetID(projectName); <span class="synComment">// プロジェクト名から ID を取得</span>

</code></pre>

<p>
変更後のコードは Find が返すオブジェクト（ここでは多分 Project みたいなクラス）に依存していないので、オブジェクト間の結合度が下がったことになる。結合度の低いプログラムは良いプログラムであり、デメテルの法則に従えば良いプログラムになるというわけだ。
</p>

<p>
でも、ちょっと待って欲しい。
</p>]]>
    </summary>
    <author>
        <name>zakio</name>
        <uri>http://zakio.net/</uri>
    </author>
    
        <category term="C++" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="OOP" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="c" label="C++" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="オブジェクト指向" label="オブジェクト指向" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="プログラミング" label="プログラミング" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="ja" xml:base="http://zakio.net/blog/">
        <![CDATA[<p>
オブジェクト指向プログラミングにおける有名な法則の一つに<a href="http://ja.wikipedia.org/wiki/%E3%83%87%E3%83%A1%E3%83%86%E3%83%AB%E3%81%AE%E6%B3%95%E5%89%87">デメテルの法則</a> (Law of Demeter, LoD) というものがある。これは、簡単に言えば「戻り値として返されたオブジェクトのメソッドを呼び出してはいけない」という法則であり、例えば次のようなコードを書くと、「それ、デメテルの法則に違反しているよ」などと言われたりするので注意が必要だ。
</p>

<pre><code>
<span class="synType">int</span> id = projects.Find(projectName).GetID(); <span class="synComment">// プロジェクト名から ID を取得</span>

</code></pre>

<p>
そして、このコードをデメテルの法則に違反しないように書き換えると、次のようになる。
</p>

<pre><code>
<span class="synType">int</span> id = projects.GetID(projectName); <span class="synComment">// プロジェクト名から ID を取得</span>

</code></pre>

<p>
変更後のコードは Find が返すオブジェクト（ここでは多分 Project みたいなクラス）に依存していないので、オブジェクト間の結合度が下がったことになる。結合度の低いプログラムは良いプログラムであり、デメテルの法則に従えば良いプログラムになるというわけだ。
</p>

<p>
でも、ちょっと待って欲しい。
</p>]]>
        <![CDATA[<p>
様々な Project を一括して管理する Projects クラスがあったとして、その Projects を扱うようなプログラムが Project に依存するのは自然な流れだと思う。また、その方がコードがスッキリする場合だってあるはずだ。
</p>

<p>
例えば、Project クラスに次のようなメンバ関数が含まれていたとする。
</p>

<pre><code>
<span class="synType">class</span> Project {
<span class="synStatement">public</span>:
  <span class="synType">const</span> std::string&amp; GetName() <span class="synType">const</span>; <span class="synComment">// プロジェクト名</span>
  <span class="synType">int</span> GetID() <span class="synType">const</span>; <span class="synComment">// ID</span>
  <span class="synType">const</span> std::string&amp; GetDescription() <span class="synType">const</span>; <span class="synComment">// プロジェクトの説明</span>

  <span class="synComment">//...</span>
};

</code></pre>

<p>
先ほどは GetID だけで済んだが、当然の流れとして GetDescription も Projects のメンバにすべきという話になるはずだ。
</p>

<pre><code>
<span class="synType">class</span> Projects {
<span class="synStatement">public</span>:
  <span class="synType">int</span> GetID(<span class="synType">const</span> std::string&amp; name) <span class="synType">const</span>; <span class="synComment">// プロジェクト名 → ID</span>
  <span class="synType">const</span> std::string&amp; GetDescription(<span class="synType">const</span> std::string&amp; name) <span class="synType">const</span>; <span class="synComment">// プロジェクト名 → プロジェクトの説明</span>

  <span class="synComment">//...</span>
};

</code></pre>

<p>
つまり、デメテルの法則に従って Projects クラスを定義していくと、Project にメンバが追加される度に Projects メンバの追加を検討することになる。
</p>

<p>
実際に Project に「メンバ」を足してみることにしよう。
</p>

<pre><code>
<span class="synType">class</span> Member {
<span class="synStatement">public</span>:
  <span class="synType">const</span> string&amp; GetName() <span class="synType">const</span>;

  <span class="synComment">//...</span>
};

<span class="synType">class</span> Project {
<span class="synStatement">public</span>:
  <span class="synType">const</span> std::string&amp; GetName() <span class="synType">const</span>; <span class="synComment">// プロジェクト名</span>
  <span class="synType">int</span> GetID() <span class="synType">const</span>; <span class="synComment">// ID</span>
  <span class="synType">const</span> std::string&amp; GetDescription() <span class="synType">const</span>; <span class="synComment">// プロジェクトの説明</span>
  <span class="synType">const</span> Member&amp; GetLeader() <span class="synType">const</span>; <span class="synComment">// リーダは一人だけ</span>
  <span class="synType">const</span> std::vector&lt;Member&gt;&amp; GetMembers() <span class="synType">const</span>; <span class="synComment">// 全メンバ（リーダも含む）</span>

  <span class="synComment">//...</span>
};

</code></pre>

<p>
メンバ違いなのはさておき、Projects からプロジェクトリーダやメンバの名前を取得するようなコードは、デメテルの法則に従えば次のようなものになるはずだ。
</p>

<pre><code>
string leaderName = projects.GetLeaderName(projectName);
vector&lt;string&gt; membersName = projects.GetMembersName(projectName);
<span class="synComment">// or</span>
string memberName = projects.GetMemberName(projectName, index); <span class="synComment">// 一人ずつ取得しても良い</span>

</code></pre>

<p>
これを実現するためには、Projects クラスに GetLeaderName, GetMembersName あるいは GetMemberName といった関数を追加しなければならない。
</p>

<pre><code>
<span class="synType">class</span> Projects {
<span class="synStatement">public</span>:
  <span class="synType">int</span> GetID(<span class="synType">const</span> std::string&amp; name) <span class="synType">const</span>; <span class="synComment">// プロジェクト名 → ID</span>
  <span class="synType">const</span> std::string&amp; GetDescription(<span class="synType">const</span> std::string&amp; name) <span class="synType">const</span>; <span class="synComment">// プロジェクト名 → プロジェクトの説明</span>

  <span class="synComment">// プロジェクト名 → プロジェクトリーダ名</span>
  <span class="synType">const</span> std::string&amp; GetLeaderName(<span class="synType">const</span> std::string&amp; name) <span class="synType">const</span>;

  <span class="synComment">// 全メンバ（リーダも含む）の名前を一括で取得する</span>
  <span class="synComment">// （他にも色々な実装が考えられるが、今回の話題ではこれで充分）</span>
  <span class="synType">const</span> std::vector&lt;std::string&gt;&amp; GetMembersName(<span class="synType">const</span> std::string&amp; name) <span class="synType">const</span>;

  <span class="synComment">// こちらの方が「戻り値のメンバを使わない」という観点から、より LoD 的な実装</span>
  std::<span class="synType">size_t</span> GetMemberCount(<span class="synType">const</span> std::string&amp; name) <span class="synType">const</span>; <span class="synComment">// メンバの数</span>
  <span class="synType">const</span> std::string&amp; GetMemberName(<span class="synType">const</span> std::string&amp; name, <span class="synType">int</span> index) <span class="synType">const</span>; <span class="synComment">// メンバ名</span>

  <span class="synComment">//...</span>
};

</code></pre>

<p>
以降、同様に Projects のメンバは肥大化の一途をたどることになる。私が Projects クラスのユーザなら「もう、いっそのこと Project に依存させてくれ！」と叫んでいるところだ。（そして多分 Member クラスも同じ理由で依存したくなるはず。）
</p>

<p>
さらに、Project や Member のインタフェースだけが肥大化の要因ではない。
</p>

<p>
プロジェクト名から何らかの情報を得るというインタフェースの他に、プロジェクト ID からも情報を得たいという要求が挙がった時のことを考えてみよう。デメテルの法則に従えば、プロジェクト ID をキーにした一連のメソッド群を用意すべし、となる。
</p>

<pre><code>
<span class="synType">class</span> Projects {
<span class="synStatement">public</span>:
  <span class="synType">int</span> GetID(<span class="synType">const</span> std::string&amp; name) <span class="synType">const</span>; <span class="synComment">// プロジェクト名 → ID</span>
  <span class="synType">const</span> std::string&amp; GetDescription(<span class="synType">const</span> std::string&amp; name) <span class="synType">const</span>; <span class="synComment">// プロジェクト名 → プロジェクトの説明</span>
  <span class="synType">const</span> std::string&amp; GetLeaderName(<span class="synType">const</span> std::string&amp; name) <span class="synType">const</span>; <span class="synComment">// プロジェクト名 → プロジェクトリーダ名</span>
  <span class="synType">const</span> std::vector&lt;std::string&gt;&amp; GetMembersName(<span class="synType">const</span> std::string&amp; name) <span class="synType">const</span>; <span class="synComment">// プロジェクト名 → 全メンバ名</span>
  std::<span class="synType">size_t</span> GetMemberCount(<span class="synType">const</span> std::string&amp; name) <span class="synType">const</span>; <span class="synComment">// プロジェクト名 → メンバの数</span>
  <span class="synType">const</span> std::string&amp; GetMemberName(<span class="synType">const</span> std::string&amp; name, <span class="synType">int</span> index) <span class="synType">const</span>; <span class="synComment">// プロジェクト名 → メンバ名</span>

<span class="synStatement">public</span>:
  <span class="synType">int</span> GetName(<span class="synType">int</span> id) <span class="synType">const</span>; <span class="synComment">// ID → プロジェクト名</span>
  <span class="synType">const</span> std::string&amp; GetDescription(<span class="synType">int</span> id) <span class="synType">const</span>; <span class="synComment">// ID → プロジェクトの説明</span>
  <span class="synType">const</span> std::string&amp; GetLeaderName(<span class="synType">int</span> id) <span class="synType">const</span>; <span class="synComment">// ID → プロジェクトリーダ名</span>
  <span class="synType">const</span> std::vector&lt;std::string&gt;&amp; GetMembersName(<span class="synType">int</span> id) <span class="synType">const</span>; <span class="synComment">// ID → 全メンバ名</span>
  std::<span class="synType">size_t</span> GetMemberCount(<span class="synType">int</span> id) <span class="synType">const</span>; <span class="synComment">// ID → メンバの数</span>
  <span class="synType">const</span> std::string&amp; GetMemberName(<span class="synType">int</span> id, <span class="synType">int</span> index) <span class="synType">const</span>; <span class="synComment">// ID → メンバ名</span>

  <span class="synComment">//...</span>
};

</code></pre>

<p>
以降、検索のキーが増える度に、同様のインタフェースが追加されることになる。
</p>

<p>
もし、デメテルの法則に従わなければ、先ほどのコードは次のようになっていたはずだ。
</p>

<pre><code>
<span class="synType">class</span> Projects {
<span class="synStatement">public</span>:
  <span class="synType">const</span> Project&amp; Find(<span class="synType">const</span> std::string&amp; name) <span class="synType">const</span>; <span class="synComment">// プロジェクト名 → Project クラス</span>
  <span class="synType">const</span> Project&amp; Find(<span class="synType">int</span> id) <span class="synType">const</span>; <span class="synComment">// ID → Project クラス</span>

  <span class="synComment">//...</span>
};

</code></pre>

<p>
これなら Find の種類が増えても Projects のメンバ関数はそれに応じて増えるだけだし、Project のメンバが増えても Projects に影響はない。先ほどよりも遥かに直交性の高いプログラムになっている。
</p>

<p>
そもそも Projects というクラスは Project を一括して管理するという役割を担っていたはずだ。リーダ名を取得するメソッドが「Project を一括して管理する」という役割に沿ったものだろうか。いや、とてもそうは思えない。こういった、クラスの役割とは異なるメンバ関数が多く含まれるクラスのことを凝集度が低いクラスと呼び、デメテルの法則に従って改変した Projects クラスは凝集度が低いクラスに変化したことになる。
</p>

<p>
ちなみに、Projects が Find によって Project を直接返すなら、プロジェクトリーダの名前を取得するコードは次のようになるだろう。
</p>

<pre><code>
string leaderName = projects.Find(projectName).GetLeader().GetName();
<span class="synComment">// あるいは</span>
string leaderName = projects.Find(projectID).GetLeader().GetName();

</code></pre>

<p>
まさに「デメテルの法則違反」なコードだ。でも、私は Projects が肥大化するよりはこの方がマシだと思えるのだが、そういった感覚はおかしいのだろうか？ 直交性を犠牲にしてまで従うべき法則なのだろうか？
</p>

<p>
デメテルの法則に従うと得られるメリットは以下の通り。
</p>

<ul>
<li>依存するクラスの数を減らすことができる（結合度の低下）</li>
<li>中間部分のインタフェースが変更されても、呼び出し側のコードを変更する必要がなくなる</li>
<li>中間クラスが持つ不要なインタフェースを隠蔽できる（むしろ隠蔽すべき）</li>
</ul>

<p>
これに対するデメリットは以下の通り。
</p>

<ul>
<li>クラスの役割があいまいになる（凝集度の低下）</li>
<li>場合によってはラッパーメソッド（委譲に必要なメンバ関数）が大量に必要となる</li>
</ul>

<p>
結局のところ、メリットとデメリットのトレードオフなだけであって、闇雲にデメテルの法則に従う必要はないはずだ。「それ、デメテルの法則に違反してるよ」と言われた時に、「それでは、直交性や凝集度を考慮した上でクラスのインタフェースを再検討してみましょう」と言ってみるのも面白いだろう。
</p>

<p>
極端な話、以下のコードだってデメテルの法則に違反している。
</p>

<pre><code>
vector&lt;Member&gt; members;
<span class="synComment">//...</span>
<span class="synStatement">for</span> (<span class="synType">size_t</span> i = <span class="synConstant">0</span>; i &lt; members.size(); ++i)
  cout &lt;&lt; members[i].GetName() &lt;&lt; endl;

</code></pre>

<p>
そう見えなければ、こう書き換えてもいい。
</p>

<pre><code>
vector&lt;Member&gt; members;
<span class="synComment">//...</span>
<span class="synStatement">for</span> (<span class="synType">size_t</span> i = <span class="synConstant">0</span>; i &lt; members.size(); ++i)
  cout &lt;&lt; members.<span class="synStatement">operator</span>[](i).GetName() &lt;&lt; endl; <span class="synComment">// ドットが2つ！ LoD 違反！</span>

</code></pre>

<p>
これをこう書き換えればデメテルの法則を違反せずに済むが......
</p>

<pre><code>
<span class="synStatement">for</span> (<span class="synType">size_t</span> i = <span class="synConstant">0</span>; i &lt; members.size(); ++i) {
  <span class="synType">const</span> Member&amp; member = members[i];
  cout &lt;&lt; member.GetName() &lt;&lt; endl; <span class="synComment">// OK. ドットは一つだけだ</span>
}

</code></pre>

<p>
それを強制させられるような職場なら、本気で転職を考えたほうが良いだろう。
</p>

<h3>参考文献</h3>

<p>
<a href="http://www.ccs.neu.edu/research/demeter/demeter-method/LawOfDemeter/paper-boy/demeter.pdf">The Paperboy, The Wallet, and The Law of Demeter (PDF)</a>
</p>

<p>
このエントリが LoD に批判的なものになってしまったので、肯定的な文献を参考に挙げておく。英文だが、現実の世界をモチーフにしたサンプルコードが分かりやすく、英語そのものも読みやすいのでお奨め。
</p>

<p>
今回は意図的に LoD に不利な条件を作り出したが、隠蔽すべきものは隠蔽するというカプセル化の大原則を忘れてはならない。トレードオフを考えつつ、LoD に従うべきときは素直に従うべし。
</p>]]>
    </content>
</entry>

<entry>
    <title>仮想関数を generic にする</title>
    <link rel="alternate" type="text/html" href="http://zakio.net/blog/2009/06/01-133549.html" />
    <id>tag:zakio.net,2009:/blog//1.15</id>

    <published>2009-06-01T04:35:49Z</published>
    <updated>2009-06-01T04:36:19Z</updated>

    <summary>
        <![CDATA[<p>
<a href="http://zakio.net/blog/2009/03/19-214446.html">C++では、メンバ関数テンプレートを仮想関数にできない</a>。ところが、C++/CLI ではテンプレートに良く似た機能である generic を仮想関数につけることができる。これにはどんなトリックが隠されているのだろう？
</p>

<p>
まずは、次のようなコードから。
</p>

<pre><code>
<span class="synStatement">public</span> <span class="synType">ref</span> <span class="synType">class</span> Base <span class="synComment">// ref class なので参照型</span>
{
<span class="synStatement">public</span>:
  <span class="synType">generic</span> &lt;<span class="synType">typename</span> T&gt; <span class="synComment">// generic を仮想関数につける</span>
  <span class="synType">virtual</span> <span class="synType">int</span> Func(T <span class="synStatement">in</span>) { <span class="synComment">// T は任意の型</span>
      <span class="synStatement">return</span> <span class="synStatement">sizeof</span>(<span class="synStatement">in</span>); <span class="synComment">// T 型のサイズを返す（本当は size_t だけど）</span>
  }
};

<span class="synStatement">public</span> <span class="synType">ref</span> <span class="synType">class</span> Derived: <span class="synStatement">public</span> Base
{
<span class="synStatement">public</span>:
  <span class="synType">generic</span> &lt;<span class="synType">typename</span> T&gt;
  <span class="synType">virtual</span> <span class="synType">int</span> Func(T <span class="synStatement">in</span>) <span class="synType">override</span> { <span class="synComment">// Base::Func を override</span>
      <span class="synStatement">return</span> <span class="synStatement">sizeof</span>(<span class="synStatement">in</span>) * <span class="synConstant">2</span>; <span class="synComment">// T 型のサイズを倍にして返す</span>
  }
};

</code></pre>

<p>
これはTがどんな型であっても正しく動作する。Derived のインスタンスを Base のハンドルで参照しても、Derived 側の Func が呼ばれる。完璧だ。
</p>

<p>
C++ では、Tの型が決まらないと仮想関数テーブルを構築できず、Tの型を知るためには全ての翻訳単位を調べなければならない。よって、このようなメンバ関数は禁止されている。そして、<a href="http://zakio.net/blog/2009/03/19-214446.html">以前のエントリ</a>では「なんだ、その都度 JIT コンパイルすればいいじゃん」という結論で終わっていた。今回は、これをもう少し調べてみようと思う。
</p>]]>
    </summary>
    <author>
        <name>zakio</name>
        <uri>http://zakio.net/</uri>
    </author>
    
        <category term=".NET Framework" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="C++/CLI" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="ccli" label="C++/CLI" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="generics" label="generics" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="template" label="template" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="virtual" label="virtual" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="ja" xml:base="http://zakio.net/blog/">
        <![CDATA[<p>
<a href="http://zakio.net/blog/2009/03/19-214446.html">C++では、メンバ関数テンプレートを仮想関数にできない</a>。ところが、C++/CLI ではテンプレートに良く似た機能である generic を仮想関数につけることができる。これにはどんなトリックが隠されているのだろう？
</p>

<p>
まずは、次のようなコードから。
</p>

<pre><code>
<span class="synStatement">public</span> <span class="synType">ref</span> <span class="synType">class</span> Base <span class="synComment">// ref class なので参照型</span>
{
<span class="synStatement">public</span>:
  <span class="synType">generic</span> &lt;<span class="synType">typename</span> T&gt; <span class="synComment">// generic を仮想関数につける</span>
  <span class="synType">virtual</span> <span class="synType">int</span> Func(T <span class="synStatement">in</span>) { <span class="synComment">// T は任意の型</span>
      <span class="synStatement">return</span> <span class="synStatement">sizeof</span>(<span class="synStatement">in</span>); <span class="synComment">// T 型のサイズを返す（本当は size_t だけど）</span>
  }
};

<span class="synStatement">public</span> <span class="synType">ref</span> <span class="synType">class</span> Derived: <span class="synStatement">public</span> Base
{
<span class="synStatement">public</span>:
  <span class="synType">generic</span> &lt;<span class="synType">typename</span> T&gt;
  <span class="synType">virtual</span> <span class="synType">int</span> Func(T <span class="synStatement">in</span>) <span class="synType">override</span> { <span class="synComment">// Base::Func を override</span>
      <span class="synStatement">return</span> <span class="synStatement">sizeof</span>(<span class="synStatement">in</span>) * <span class="synConstant">2</span>; <span class="synComment">// T 型のサイズを倍にして返す</span>
  }
};

</code></pre>

<p>
これはTがどんな型であっても正しく動作する。Derived のインスタンスを Base のハンドルで参照しても、Derived 側の Func が呼ばれる。完璧だ。
</p>

<p>
C++ では、Tの型が決まらないと仮想関数テーブルを構築できず、Tの型を知るためには全ての翻訳単位を調べなければならない。よって、このようなメンバ関数は禁止されている。そして、<a href="http://zakio.net/blog/2009/03/19-214446.html">以前のエントリ</a>では「なんだ、その都度 JIT コンパイルすればいいじゃん」という結論で終わっていた。今回は、これをもう少し調べてみようと思う。
</p>]]>
        <![CDATA[<p>
「JIT コンパイルすればいいじゃん」と言ってはみたものの、JIT コンパイラはソースコードを直接ネイティブコードにコンパイルするわけではない。ソースコードは MSIL という中間言語にコンパイルされており、JIT コンパイラは、この MSIL をネイティブコードにコンパイルするだけだ。
</p>

<p>
ということは、C++ の「仮想関数テーブル作成問題」は、この MSIL を作成する段階で問題にならないだろうか。先ほどのコードを ILDasm で見てみると、このようなコードになっていた。
</p>

<pre><code>
.method <span class="synStatement">public</span> hidebysig newslot <span class="synType">virtual</span> 
        instance int32  Func&lt;T&gt;(!!T '<span class="synStatement">in</span>') cil managed
{
  <span class="synComment">// Code size       9 (0x9)</span>
  .maxstack  <span class="synConstant">1</span>
  .locals ([<span class="synConstant">0</span>] int32 V_0)
  <span class="synStatement">IL_0000</span>:  <span class="synStatement">sizeof</span>     !!T
  <span class="synStatement">IL_0006</span>:  stloc<span class="synConstant">.0</span>
  <span class="synStatement">IL_0007</span>:  ldloc<span class="synConstant">.0</span>
  <span class="synStatement">IL_0008</span>:  ret
} <span class="synComment">// end of method Base::Func</span>

.method <span class="synStatement">public</span> hidebysig <span class="synType">virtual</span> instance int32 
        Func&lt;T&gt;(!!T '<span class="synStatement">in</span>') cil managed
{
  <span class="synComment">// Code size       11 (0xb)</span>
  .maxstack  <span class="synConstant">2</span>
  .locals ([<span class="synConstant">0</span>] int32 V_0)
  <span class="synStatement">IL_0000</span>:  <span class="synStatement">sizeof</span>     !!T
  <span class="synStatement">IL_0006</span>:  ldc.i4<span class="synConstant">.2</span>
  <span class="synStatement">IL_0007</span>:  mul
  <span class="synStatement">IL_0008</span>:  stloc<span class="synConstant">.0</span>
  <span class="synStatement">IL_0009</span>:  ldloc<span class="synConstant">.0</span>
  <span class="synStatement">IL_000a</span>:  ret
} <span class="synComment">// end of method Derived::Func</span>

</code></pre>

<p>
よく見ると、なんと T が T のままコンパイルされている。そして、sizeof が T をそのまま処理している。MSIL のレベルで T を T として扱っているということは、JIT コンパイルの段階で T の型に応じたネイティブコードを生成可能ということ。なるほど、ここまでは予想通り。
</p>

<p>
でも、これは MSIL の sizeof が T を T として扱えることに頼っている。sizeof じゃなかったらどうなるのだろう。
</p>

<pre><code>
<span class="synStatement">public</span> <span class="synType">ref</span> <span class="synType">class</span> Base
{
<span class="synStatement">public</span>:
  <span class="synType">generic</span> &lt;<span class="synType">typename</span> T&gt;
  <span class="synType">virtual</span> System::String^ Func(T <span class="synStatement">in</span>) {
      <span class="synStatement">return</span> <span class="synStatement">in</span>-&gt;ToString(); <span class="synComment">// 今度は T に対して ToString メソッドを呼び出してみた</span>
  }
};

<span class="synStatement">public</span> <span class="synType">ref</span> <span class="synType">class</span> Derived: <span class="synStatement">public</span> Base
{
<span class="synStatement">public</span>:
  <span class="synType">generic</span> &lt;<span class="synType">typename</span> T&gt;
  <span class="synType">virtual</span> System::String^ Func(T <span class="synStatement">in</span>) <span class="synType">override</span> {
      <span class="synStatement">return</span> <span class="synStatement">in</span>-&gt;ToString() + <span class="synConstant">&quot; (Derived)&quot;</span>; <span class="synComment">// Derived 側の処理も上書き</span>
  }
};

</code></pre>

<p>
今度は T 型の変数 in に対して ToString メソッドを呼び出してみた。ILDasm の出力は次の通り。
</p>

<pre><code>
.method <span class="synStatement">public</span> hidebysig newslot <span class="synType">virtual</span> 
        instance string  Func&lt;T&gt;(!!T '<span class="synStatement">in</span>') cil managed
{
  <span class="synComment">// Code size       16 (0x10)</span>
  .maxstack  <span class="synConstant">1</span>
  .locals ([<span class="synConstant">0</span>] string V_0)
  <span class="synStatement">IL_0000</span>:  ldarga.s   '<span class="synStatement">in</span>'
  <span class="synStatement">IL_0002</span>:  constrained. !!T
  <span class="synStatement">IL_0008</span>:  callvirt   instance string [mscorlib]System.Object::ToString()
  <span class="synStatement">IL_000d</span>:  stloc<span class="synConstant">.0</span>
  <span class="synStatement">IL_000e</span>:  ldloc<span class="synConstant">.0</span>
  <span class="synStatement">IL_000f</span>:  ret
} <span class="synComment">// end of method Base::Func</span>

.method <span class="synStatement">public</span> hidebysig <span class="synType">virtual</span> instance string 
        Func&lt;T&gt;(!!T '<span class="synStatement">in</span>') cil managed
{
  <span class="synComment">// Code size       26 (0x1a)</span>
  .maxstack  <span class="synConstant">2</span>
  .locals ([<span class="synConstant">0</span>] string V_0)
  <span class="synStatement">IL_0000</span>:  ldarga.s   '<span class="synStatement">in</span>'
  <span class="synStatement">IL_0002</span>:  constrained. !!T
  <span class="synStatement">IL_0008</span>:  callvirt   instance string [mscorlib]System.Object::ToString()
  <span class="synStatement">IL_000d</span>:  ldstr      <span class="synConstant">&quot; (Derived)&quot;</span>
  <span class="synStatement">IL_0012</span>:  call       string [mscorlib]System.String::Concat(string,
                                                              string)
  <span class="synStatement">IL_0017</span>:  stloc<span class="synConstant">.0</span>
  <span class="synStatement">IL_0018</span>:  ldloc<span class="synConstant">.0</span>
  <span class="synStatement">IL_0019</span>:  ret
} <span class="synComment">// end of method Derived::Func</span>

</code></pre>

<p>
IL_0008 の部分で、<a href="http://msdn.microsoft.com/ja-jp/library/system.reflection.emit.opcodes.callvirt.aspx">callvirt</a> という命令を使って Object::ToString() を呼び出している。この部分に T はなく、T は1つ前の <a href="http://msdn.microsoft.com/ja-jp/library/system.reflection.emit.opcodes.constrained.aspx">constrained</a> で使われている。T がどんな型であっても constrained が良きに計らってくれて、実行時の型に応じた ToString() が呼ばれるというわけだ。すばらしい。
</p>

<p>
ToString は System::Object のメソッドなので、どんな型からも（場合によってはボックス化を伴って）呼び出すことができる。もう少しハードルを上げてみよう。T という型が持っている「かも知れない」メソッドを呼び出してみたらどうだろう。
</p>

<pre><code>
<span class="synStatement">public</span> <span class="synType">ref</span> <span class="synType">class</span> Base
{
<span class="synStatement">public</span>:
  <span class="synType">generic</span> &lt;<span class="synType">typename</span> T&gt;
  <span class="synType">virtual</span> System::String^ Func(T <span class="synStatement">in</span>) {
      <span class="synStatement">return</span> <span class="synStatement">in</span>-&gt;Func1(); <span class="synComment">// エラー: T は System::Object と見なされるため、Func1 は呼べない</span>
  }
};

<span class="synStatement">public</span> <span class="synType">ref</span> <span class="synType">class</span> Derived: <span class="synStatement">public</span> Base
{
<span class="synStatement">public</span>:
  <span class="synType">generic</span> &lt;<span class="synType">typename</span> T&gt;
  <span class="synType">virtual</span> System::String^ Func(T <span class="synStatement">in</span>) <span class="synType">override</span> {
      <span class="synStatement">return</span> <span class="synStatement">in</span>-&gt;Func2(); <span class="synComment">// エラー: Func2 も System::Object のメンバではない</span>
  }
};

</code></pre>

<p>
エラーだ。コンパイルできない。どうやら System::Object のメンバではないメソッドを呼び出すことができないようだ。このエラーを取り除くためには、次のように T が何者なのかを教えてやる必要がある。
</p>

<pre><code>
<span class="synStatement">public</span> interface <span class="synType">class</span> HasFunc {
  System::String^ Func1();
  System::String^ Func2();
};

<span class="synStatement">public</span> <span class="synType">ref</span> <span class="synType">class</span> Base
{
<span class="synStatement">public</span>:
  <span class="synType">generic</span> &lt;<span class="synType">typename</span> T&gt; <span class="synStatement">where</span> T: HasFunc <span class="synComment">// T が何者かを教える</span>
  <span class="synType">virtual</span> System::String^ Func(T <span class="synStatement">in</span>) {
      <span class="synStatement">return</span> <span class="synStatement">in</span>-&gt;Func1(); <span class="synComment">// T は HasFunc なので、Func1 を呼べる</span>
  }
};

<span class="synStatement">public</span> <span class="synType">ref</span> <span class="synType">class</span> Derived: <span class="synStatement">public</span> Base
{
<span class="synStatement">public</span>:
  <span class="synType">generic</span> &lt;<span class="synType">typename</span> T&gt; <span class="synComment">// override しているので、T が HasFunc であることは既知</span>
  <span class="synType">virtual</span> System::String^ Func(T <span class="synStatement">in</span>) <span class="synType">override</span> {
      <span class="synStatement">return</span> <span class="synStatement">in</span>-&gt;Func2(); <span class="synComment">// T は HasFunc なので、Func2 を呼べる</span>
  }
};

</code></pre>

<p>
ふむふむ、なるほど。先ほどは T が何者なのか分からなかったので、どんな型からも呼び出すことができる System::Object のメソッドしか受け付けなかったというわけか。今回は、T が HasFunc というインタフェースを持っていることが分かっているので、Func1 も Func2 を呼び出せる......って、当たり前じゃないか。
</p>

<p>
それなら、こんな風にしても同じ事。インタフェースを知る必要があるなら、あえて generic にしなくても書ける。
</p>

<pre><code>
<span class="synStatement">public</span> interface <span class="synType">class</span> HasFunc {
  System::String^ Func1();
  System::String^ Func2();
};

<span class="synStatement">public</span> <span class="synType">ref</span> <span class="synType">class</span> Base
{
<span class="synStatement">public</span>:
  <span class="synType">virtual</span> System::String^ Func(HasFunc^ <span class="synStatement">in</span>) { <span class="synComment">// 無理に generic にしなくても、こうすればよいだけ</span>
      <span class="synStatement">return</span> <span class="synStatement">in</span>-&gt;Func1(); <span class="synComment">// in は HasFunc なので、Func1 を呼び出せる</span>
  }
};

<span class="synStatement">public</span> <span class="synType">ref</span> <span class="synType">class</span> Derived: <span class="synStatement">public</span> Base
{
<span class="synStatement">public</span>:
  <span class="synType">virtual</span> System::String^ Func(HasFunc^ <span class="synStatement">in</span>) <span class="synType">override</span> {
      <span class="synStatement">return</span> <span class="synStatement">in</span>-&gt;Func2(); <span class="synComment">// Func2 も呼び出せる</span>
  }
};

</code></pre>

<p>
.NET の generics は、コンパイル時にソースコードを要求しないという利点を求めた結果、多分、C++ ユーザにとって template を使う大きな理由の一つである「静的なダックタイピング」を切り捨てざるを得なかったのだろう。
</p>

<p>
これまで generic を template のようなものだと思っていたが、これではまるで別物だ。考えを改めなければならない。
</p>]]>
    </content>
</entry>

<entry>
    <title>Pimpl イディオムのお手軽な実装</title>
    <link rel="alternate" type="text/html" href="http://zakio.net/blog/2009/04/15-222117.html" />
    <id>tag:zakio.net,2009:/blog//1.14</id>

    <published>2009-04-15T13:21:17Z</published>
    <updated>2009-04-16T01:43:47Z</updated>

    <summary>
        <![CDATA[<p>
Pimpl イディオム（Handle-Body, Compilation or Compiler Firewall, Cheshire Cat とも呼ばれたりする）は実装の詳細を隠蔽したい時に用いられる手法だが、内部が委譲の嵐になったり、ポインタの扱いに注意を払う必要があったりと、気軽には使い難いパターンの一つではある。内部の委譲に関しては Pimpl の性質上仕方がないものとして諦められるが、せめてポインタ周りだけでもお手軽に扱えるようにならないだろうか、というのが今回のお題だ。
</p>

<p>
教科書に載っているような Pimpl の実装は、大抵の場合、次の例の前半部分まで。こうやって隠蔽した Impl のポインタ pImpl_ を正しく扱うためには、コンストラクタ、デストラクタ、コピーコンストラクタ、代入演算子を「正しく」実装しなければならない。
</p>

<pre><code>
<span class="synType">class</span> PimplTest {
<span class="synStatement">public</span>:
  <span class="synComment">// ... 外部に公開するインタフェース</span>

<span class="synStatement">private</span>:
  <span class="synType">class</span> Impl; <span class="synComment">// 実装の詳細は Impl に隠蔽し、</span>
  Impl* pImpl_; <span class="synComment">// そのポインタを保持する</span>

<span class="synComment">// Impl を正しく扱うためには、以下のコードを「正しく」書かなければならない</span>
<span class="synStatement">public</span>:
  PimplTest(); <span class="synComment">// ここで new</span>
  ~PimplTest(); <span class="synComment">// ここで delete</span>
  PimplTest(<span class="synType">const</span> PimplTest&amp; obj); <span class="synComment">// Impl に対する深いコピーが必要</span>
  PimplTest&amp; <span class="synStatement">operator</span> = (<span class="synType">const</span> PimplTest&amp; rhs); <span class="synComment">// こちらも同様に深いコピー</span>
};

</code></pre>

<p>
時々、ポインタ周りを楽にするために shared_ptr を使って Pimpl イディオムを実装している例を見かけるが、これではコピーや代入時に実装の詳細が共有されてしまう。コピーや代入を禁止しても構わない場合ならこれで充分かも知れないが、そうでない場合は自前のコピーコンストラクタや代入演算子を用意する必要があるため、やはり、お手軽とは言い難いだろう。
</p>]]>
    </summary>
    <author>
        <name>zakio</name>
        <uri>http://zakio.net/</uri>
    </author>
    
        <category term="C++" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="c" label="C++" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="pimpl" label="Pimpl" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="ja" xml:base="http://zakio.net/blog/">
        <![CDATA[<p>
Pimpl イディオム（Handle-Body, Compilation or Compiler Firewall, Cheshire Cat とも呼ばれたりする）は実装の詳細を隠蔽したい時に用いられる手法だが、内部が委譲の嵐になったり、ポインタの扱いに注意を払う必要があったりと、気軽には使い難いパターンの一つではある。内部の委譲に関しては Pimpl の性質上仕方がないものとして諦められるが、せめてポインタ周りだけでもお手軽に扱えるようにならないだろうか、というのが今回のお題だ。
</p>

<p>
教科書に載っているような Pimpl の実装は、大抵の場合、次の例の前半部分まで。こうやって隠蔽した Impl のポインタ pImpl_ を正しく扱うためには、コンストラクタ、デストラクタ、コピーコンストラクタ、代入演算子を「正しく」実装しなければならない。
</p>

<pre><code>
<span class="synType">class</span> PimplTest {
<span class="synStatement">public</span>:
  <span class="synComment">// ... 外部に公開するインタフェース</span>

<span class="synStatement">private</span>:
  <span class="synType">class</span> Impl; <span class="synComment">// 実装の詳細は Impl に隠蔽し、</span>
  Impl* pImpl_; <span class="synComment">// そのポインタを保持する</span>

<span class="synComment">// Impl を正しく扱うためには、以下のコードを「正しく」書かなければならない</span>
<span class="synStatement">public</span>:
  PimplTest(); <span class="synComment">// ここで new</span>
  ~PimplTest(); <span class="synComment">// ここで delete</span>
  PimplTest(<span class="synType">const</span> PimplTest&amp; obj); <span class="synComment">// Impl に対する深いコピーが必要</span>
  PimplTest&amp; <span class="synStatement">operator</span> = (<span class="synType">const</span> PimplTest&amp; rhs); <span class="synComment">// こちらも同様に深いコピー</span>
};

</code></pre>

<p>
時々、ポインタ周りを楽にするために shared_ptr を使って Pimpl イディオムを実装している例を見かけるが、これではコピーや代入時に実装の詳細が共有されてしまう。コピーや代入を禁止しても構わない場合ならこれで充分かも知れないが、そうでない場合は自前のコピーコンストラクタや代入演算子を用意する必要があるため、やはり、お手軽とは言い難いだろう。
</p>]]>
        <![CDATA[<p>
例えば、先ほどの例を少しだけ肉付けして、shared_ptr を使った例に書き換えると次のようになる。
</p>

<pre><code>
<span class="synType">class</span> PimplTest {
<span class="synStatement">public</span>:
  PimplTest();

<span class="synComment">// 値の読み書きを表現</span>
<span class="synStatement">public</span>:
  <span class="synType">void</span> SetVal(<span class="synType">int</span> val);
  <span class="synType">int</span> GetVal() <span class="synType">const</span>;

<span class="synComment">// 実装の詳細</span>
<span class="synStatement">private</span>:
  <span class="synType">class</span> Impl;
  std::tr1::shared_ptr&lt;Impl&gt; pImpl_; <span class="synComment">// コピーさえしなければ、これで間に合うが......</span>
};

</code></pre>

<p>
cpp 側はこんな感じ。
</p>

<pre><code>
<span class="synComment">// 実装の詳細</span>
<span class="synType">class</span> PimplTest::Impl {
  <span class="synType">int</span> val_;
<span class="synStatement">public</span>:
  Impl(): val_(<span class="synType">int</span>()) {}
  <span class="synType">void</span> SetVal(<span class="synType">int</span> val) { val_ = val; }
  <span class="synType">int</span> GetVal() <span class="synType">const</span> { <span class="synStatement">return</span> val_; }
};

<span class="synComment">// コンストラクタで new するだけなので楽チン</span>
PimplTest::PimplTest(): pImpl_(<span class="synStatement">new</span> Impl) {}

<span class="synComment">// 委譲の嵐</span>
<span class="synType">void</span> PimplTest::SetVal(<span class="synType">int</span> val) { pImpl_-&gt;SetVal(val); }
<span class="synType">int</span> PimplTest::GetVal() <span class="synType">const</span> { <span class="synStatement">return</span> pImpl_-&gt;GetVal(); }

</code></pre>

<p>
このように実装してしまうと、shared_ptr が持つ「コピー時に参照先（この場合は Impl のインスタンス）を共有する」という性質から、次のような問題が生じてしまう。
</p>

<pre><code>
<span class="synComment">// PimplTest のインスタンスに 1 と 2 をセットする</span>
PimplTest test1, test2;
test1.SetVal(<span class="synConstant">1</span>);
test2.SetVal(<span class="synConstant">2</span>);

<span class="synComment">// 当然、1, 2 と表示される</span>
cout &lt;&lt; test1.GetVal() &lt;&lt; <span class="synConstant">&quot;, &quot;</span> &lt;&lt; test2.GetVal() &lt;&lt; endl;

test1 = test2; <span class="synComment">// test2 の内容を test1 に代入（これで test1 が 2 になるはず）</span>
test2.SetVal(<span class="synConstant">20</span>); <span class="synComment">// test2 は 20 に変更</span>

<span class="synComment">// 2, 20 と表示されることを期待するが、</span>
<span class="synComment">// 実際には test1 と test2 は同じ Impl を参照しているため、20, 20 と表示される</span>
cout &lt;&lt; test1.GetVal() &lt;&lt; <span class="synConstant">&quot;, &quot;</span> &lt;&lt; test2.GetVal() &lt;&lt; endl;

</code></pre>

<p>
つまり、Pimpl に適したスマートポインタは、次の2つの機能を兼ね備えていなければならないということだ。
</p>

<ol>
<li>不完全型を受け付ける（クラスの先行宣言だけでコンパイル可能）</li>
<li>値のセマンティクスを持つ（勝手に深いコピーをしてくれる）</li>
</ol>

<p>
shared_ptr は1つ目の機能を deleter によって実現しているが、残念ながら2番目の機能が期待通りではない。どこかに上記の機能を兼ね備えた Pimpl に最適なスマートポインタはないかと探し回ったが、探し方が悪いのだろう。満足のいくものを見つけることは出来なかった。そこで、勉強も兼ねて自作に踏み切ってみることにした。車輪の再発明かも知れないが、結構勉強になったので私的には大満足だ。
</p>

<p>
気に入った方は好きに使っていただいて構わないし、改変や商用利用、その他諸々何でもアリ。ただし、当然ながら無保証なのでご注意を。
</p>

<p>
この特別な Pimpl イディオム用のスマートポインタ Pimpl を使えば、先ほどのコードが次のように変化し、
</p>

<pre><code>
<span class="synType">class</span> PimplTest {
<span class="synStatement">public</span>:
  PimplTest();

<span class="synStatement">public</span>:
  <span class="synType">void</span> SetVal(<span class="synType">int</span> val);
  <span class="synType">int</span> GetVal() <span class="synType">const</span>;

<span class="synStatement">private</span>:
  <span class="synType">class</span> Impl;
  Pimpl&lt;Impl&gt; pImpl_; <span class="synComment">// この部分を Pimpl に変更</span>
};

</code></pre>

<p>
実行結果も期待通りになる。
</p>

<pre><code>
<span class="synComment">// PimplTest のインスタンスに 1 と 2 をセットする</span>
PimplTest test1, test2;
test1.SetVal(<span class="synConstant">1</span>);
test2.SetVal(<span class="synConstant">2</span>);

<span class="synComment">// 当然、1, 2 と表示される</span>
cout &lt;&lt; test1.GetVal() &lt;&lt; <span class="synConstant">&quot;, &quot;</span> &lt;&lt; test2.GetVal() &lt;&lt; endl;

test1 = test2; <span class="synComment">// test2 の内容を test1 に代入して、</span>
test2.SetVal(<span class="synConstant">20</span>); <span class="synComment">// test2 は 20 に変更</span>

<span class="synComment">// 今度は期待通り 2, 20 と表示される</span>
cout &lt;&lt; test1.GetVal() &lt;&lt; <span class="synConstant">&quot;, &quot;</span> &lt;&lt; test2.GetVal() &lt;&lt; endl;

</code></pre>

<p>
Pimpl の実装は以下の通り。これを適当な namespace に入れてインクルードガードを付ければ Pimpl.h の完成だ。結構便利に使えると思うのだが如何だろう。
</p>

<pre><code>
<span class="synComment">// 不完全型を受け付けるためのインタフェース</span>
<span class="synComment">// ポインタを void* で扱っている部分がミソ</span>
<span class="synType">class</span> ImplHolderBase {
<span class="synStatement">public</span>:
  <span class="synType">virtual</span> ~ImplHolderBase() {}
  <span class="synType">virtual</span> ImplHolderBase* Clone() <span class="synType">const</span> = <span class="synConstant">0</span>;
  <span class="synType">virtual</span> <span class="synType">void</span> CopyTo(ImplHolderBase* pHolder) <span class="synType">const</span> = <span class="synConstant">0</span>;
  <span class="synType">virtual</span> <span class="synType">void</span>* GetPtr() = <span class="synConstant">0</span>;
  <span class="synType">virtual</span> <span class="synType">const</span> <span class="synType">void</span>* GetPtr() <span class="synType">const</span> = <span class="synConstant">0</span>;
};

<span class="synComment">// ポインタを保持するクラス</span>
<span class="synType">template</span> &lt;<span class="synType">class</span> T&gt;
<span class="synType">class</span> ImplHolder: <span class="synStatement">public</span> ImplHolderBase {
  T* ptr_; <span class="synComment">// これが Impl の実体</span>
<span class="synStatement">public</span>:
  <span class="synType">explicit</span> ImplHolder(T* ptr): ptr_(ptr) {}
  <span class="synType">virtual</span> ~ImplHolder() {
      <span class="synStatement">delete</span> ptr_;
  }
  <span class="synType">virtual</span> ImplHolderBase* Clone() <span class="synType">const</span> {
      <span class="synStatement">return</span> <span class="synStatement">new</span> ImplHolder(<span class="synStatement">new</span> T(*ptr_)); <span class="synComment">// ここで T のコピーコンストラクタが呼ばれる</span>
  }
  <span class="synType">virtual</span> <span class="synType">void</span> CopyTo(ImplHolderBase* pHolder) <span class="synType">const</span> {
      <span class="synComment">// ImplHolder 以外は考えられないので、static_cast で変換可能</span>
      *(<span class="synStatement">static_cast</span>&lt;ImplHolder*&gt;(pHolder)-&gt;ptr_) = *ptr_; <span class="synComment">// ここで T の代入演算子が呼ばれる</span>
  }
  <span class="synType">virtual</span> <span class="synType">void</span>* GetPtr() { <span class="synStatement">return</span> ptr_; }
  <span class="synType">virtual</span> <span class="synType">const</span> <span class="synType">void</span>* GetPtr() <span class="synType">const</span> { <span class="synStatement">return</span> ptr_; }
<span class="synStatement">private</span>: <span class="synComment">// 念のためコピーと代入を禁止しておく</span>
  ImplHolder(<span class="synType">const</span> ImplHolder&amp;); <span class="synComment">// 未実装</span>
  ImplHolder&amp; <span class="synStatement">operator</span> = (<span class="synType">const</span> ImplHolder&amp;); <span class="synComment">// 未実装</span>
};

<span class="synComment">// Pimpl クラスの実体</span>
<span class="synType">template</span> &lt;<span class="synType">class</span> T&gt;
<span class="synType">class</span> Pimpl {
  ImplHolderBase* pHolder_; <span class="synComment">// T に依存しない</span>
<span class="synStatement">public</span>:
  <span class="synType">explicit</span> Pimpl(T* ptr): pHolder_(<span class="synStatement">new</span> ImplHolder&lt;T&gt;(ptr)) {} <span class="synComment">// この時点で T の型が決まる</span>
  ~Pimpl() {
      <span class="synStatement">delete</span> pHolder_; <span class="synComment">// T が不完全型でも問題ない</span>
  }
  Pimpl(<span class="synType">const</span> Pimpl&amp; init): pHolder_(init.pHolder_-&gt;Clone()) {} <span class="synComment">// コピーコンストラクタは Clone で対応</span>
  Pimpl&amp; <span class="synStatement">operator</span> = (<span class="synType">const</span> Pimpl&amp; rhs) {
      rhs.pHolder_-&gt;CopyTo(pHolder_); <span class="synComment">// 代入は CopyTo で対応</span>
      <span class="synStatement">return</span> *<span class="synStatement">this</span>;
  }
  T&amp; <span class="synStatement">operator</span> * () { <span class="synStatement">return</span> *(<span class="synStatement">static_cast</span>&lt;T*&gt;(pHolder_-&gt;GetPtr())); }
  <span class="synType">const</span> T&amp; <span class="synStatement">operator</span> * () <span class="synType">const</span> { <span class="synStatement">return</span> *(<span class="synStatement">static_cast</span>&lt;<span class="synType">const</span> T*&gt;(pHolder_-&gt;GetPtr())); }
  T* <span class="synStatement">operator</span> -&gt; () { <span class="synStatement">return</span> &amp;(**<span class="synStatement">this</span>); }
  <span class="synType">const</span> T* <span class="synStatement">operator</span> -&gt; () <span class="synType">const</span> { <span class="synStatement">return</span> &amp;(**<span class="synStatement">this</span>); }
};

</code></pre>

<p>
ぜひ、お試しあれ！
</p>]]>
    </content>
</entry>

<entry>
    <title>コレクションの永続化</title>
    <link rel="alternate" type="text/html" href="http://zakio.net/blog/2009/04/06-221625.html" />
    <id>tag:zakio.net,2009:/blog//1.12</id>

    <published>2009-04-06T13:16:25Z</published>
    <updated>2009-04-06T13:16:27Z</updated>

    <summary>
        <![CDATA[<p>
.NET Framework で独自のコントロールを作りたい場合は、UserControl から派生させたクラスを用意すればよい。一般的に、自作コントロールには独自のプロパティも含まれており、そのプロパティが自作クラスになっていることも多いはず。今回は、自作クラスの配列をプロパティとして持たせたところ大ハマリしたという話。
</p>

<p>
ある自作コントロールに自作クラス MyItem の配列をプロパティとして持たせたいと思い、System::Collections::Generic::List&lt;MyItem^&gt;^ 型のプロパティ MyItemList を追加することにした。cli::array ではなく List を使っているのは vector っぽく使いたいためだが、この違いは本質ではない（と思う）。悲劇の始まりは次のようなコードからだ。
</p>

<pre><code>
<span class="synType">ref</span> <span class="synType">class</span> MyItem;
<span class="synType">ref</span> <span class="synType">class</span> MyCtrl : <span class="synStatement">public</span> System::Windows::Forms::UserControl
{
<span class="synComment">// ... 色々あって、</span>

<span class="synStatement">private</span>:
  System::Collections::Generic::List&lt;MyItem^&gt;^ m_itemList; <span class="synComment">// リストの実体</span>

<span class="synStatement">public</span>:
  MyCtrl(<span class="synType">void</span>) {
      InitializeComponent();

      <span class="synComment">// コンストラクタで m_itemList を確保する</span>
      m_itemList = <span class="synStatement">gcnew</span> System::Collections::Generic::List&lt;MyItem^&gt;;
  }

<span class="synStatement">public</span>:
  <span class="synType">property</span> System::Collections::Generic::List&lt;MyItem^&gt;^ MyItemList { <span class="synComment">// このプロパティは</span>
      System::Collections::Generic::List&lt;MyItem^&gt;^ get() { <span class="synComment">// get だけしか持っていない（set は許可しない）</span>
          <span class="synStatement">return</span> m_itemList; <span class="synComment">// 中身は自由にしても構わないが、リストそのものはコチラで管理させてくれ</span>
      }
  }

<span class="synComment">// ... 色々あるよね</span>
};

</code></pre>]]>
    </summary>
    <author>
        <name>zakio</name>
        <uri>http://zakio.net/</uri>
    </author>
    
        <category term=".NET Framework" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="C++/CLI" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="netframework" label=".NET Framework" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="ccli" label="C++/CLI" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="designerserializationvisibility" label="DesignerSerializationVisibility" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="usercontrol" label="UserControl" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="カスタムコントロール" label="カスタムコントロール" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="永続化" label="永続化" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="ja" xml:base="http://zakio.net/blog/">
        <![CDATA[<p>
.NET Framework で独自のコントロールを作りたい場合は、UserControl から派生させたクラスを用意すればよい。一般的に、自作コントロールには独自のプロパティも含まれており、そのプロパティが自作クラスになっていることも多いはず。今回は、自作クラスの配列をプロパティとして持たせたところ大ハマリしたという話。
</p>

<p>
ある自作コントロールに自作クラス MyItem の配列をプロパティとして持たせたいと思い、System::Collections::Generic::List&lt;MyItem^&gt;^ 型のプロパティ MyItemList を追加することにした。cli::array ではなく List を使っているのは vector っぽく使いたいためだが、この違いは本質ではない（と思う）。悲劇の始まりは次のようなコードからだ。
</p>

<pre><code>
<span class="synType">ref</span> <span class="synType">class</span> MyItem;
<span class="synType">ref</span> <span class="synType">class</span> MyCtrl : <span class="synStatement">public</span> System::Windows::Forms::UserControl
{
<span class="synComment">// ... 色々あって、</span>

<span class="synStatement">private</span>:
  System::Collections::Generic::List&lt;MyItem^&gt;^ m_itemList; <span class="synComment">// リストの実体</span>

<span class="synStatement">public</span>:
  MyCtrl(<span class="synType">void</span>) {
      InitializeComponent();

      <span class="synComment">// コンストラクタで m_itemList を確保する</span>
      m_itemList = <span class="synStatement">gcnew</span> System::Collections::Generic::List&lt;MyItem^&gt;;
  }

<span class="synStatement">public</span>:
  <span class="synType">property</span> System::Collections::Generic::List&lt;MyItem^&gt;^ MyItemList { <span class="synComment">// このプロパティは</span>
      System::Collections::Generic::List&lt;MyItem^&gt;^ get() { <span class="synComment">// get だけしか持っていない（set は許可しない）</span>
          <span class="synStatement">return</span> m_itemList; <span class="synComment">// 中身は自由にしても構わないが、リストそのものはコチラで管理させてくれ</span>
      }
  }

<span class="synComment">// ... 色々あるよね</span>
};

</code></pre>]]>
        <![CDATA[<p>
C++/CLI は const まわりが貧弱なので不安でたまらなくなるが、せめてもの反抗として MyItemList プロパティからは set を取り除いてみた。ちなみに MyItem 自体はラベルやら色やらの情報が格納された単純なもの。このコントロールは MyItemList 内の MyItem 群を描画するのが目的だ。
</p>

<pre><code>
<span class="synComment">// リストに格納されるモノ</span>
<span class="synType">ref</span> <span class="synType">class</span> MyItem {
<span class="synStatement">public</span>:
  <span class="synType">property</span> System::String^ Label; <span class="synComment">// ラベルやら</span>
  <span class="synType">property</span> System::Drawing::Color ForeColor; <span class="synComment">// 色やら</span>
  <span class="synComment">// ... その他諸々（今回は省略）</span>
};

</code></pre>

<p>
コンパイルは成功するし、このコントロールをフォームに貼り付けることもできる。しかも、コントロールのプロパティには「その他」の項目として MyItemList が入っているというオマケ付き。コレクションの右にあるボタンをクリックすると MyItem のコレクションエディタが起動し、MyItemList に MyItem を追加したり編集したりと、もう至れり尽くせり状態だ。
</p>

<p>
コレクションエディタ上で MyItem を追加、編集して、いざコンパイル。
</p>

<p>
「あれ？ MyItem が消えたぞ」
</p>

<p>
何回やっても結果は同じ。コンパイルさえしなければ何も問題はないのだが、それでは意味がない。
</p>

<p>
色々調べた結果、MyItemList の <a href="http://msdn.microsoft.com/ja-jp/library/system.componentmodel.designerserializationvisibilityattribute(VS.80).aspx">DesignerSerializationVisibility 属性</a>を Content にしなければならないことが分かった（デフォルト値は Visible）。 こうすることで、MyItemList の Content、つまり「中身」を永続化可能にするというわけだ。
</p>

<pre><code>
[DesignerSerializationVisibility(DesignerSerializationVisibility::Content)] <span class="synComment">// これが必要</span>
<span class="synType">property</span> System::Collections::Generic::List&lt;MyItem^&gt;^ MyItemList {
  System::Collections::Generic::List&lt;MyItem^&gt;^ get() {
      <span class="synStatement">return</span> m_itemList;
  }
}

</code></pre>

<p>
これで MyItemList の中身が保存されるようになったのだが、今度はコレクションの中身が空でもデザイナ上ではボールド表示、つまり「初期値と違う」と主張し始めた。MyItemList 上の右クリックで初期化しようとしても、リセット自体がグレーアウトされている。
</p>

<p>
「あぁ、確かこれは <a href="http://msdn.microsoft.com/ja-jp/library/system.componentmodel.defaultvalueattribute(VS.80).aspx">DefaultValue 属性</a>だったな」と思ったが、今回は MyItemList を自前で管理しているため、リテラルとしての初期値が存在しない。初期値というよりは、初期化メソッドが必要なのだ。
</p>

<p>
さらに調査を進めると、こういう場合は <a href="http://msdn.microsoft.com/ja-jp/library/53b8022e(VS.80).aspx">ShouldSerialize, Reset メソッド</a>を使えばよいことが分かった。最初は何を言っているのか良く分からなかったのだが、どうやら .NET Framework では ShouldSerialize<em>プロパティ名</em> と Reset<em>プロパティ名</em>の2つのメソッド名を特別扱いするという仕様のようだ。
</p>

<p>
つまり、こういうこと。
</p>

<pre><code>
<span class="synComment">// MyItemList という名前のプロパティがあれば、</span>
<span class="synComment">// ShouldSerializeMyItemList と ResetMyItemList という2つのメソッドが特別扱いされる。</span>
[DesignerSerializationVisibility(DesignerSerializationVisibility::Content)]
<span class="synType">property</span> System::Collections::Generic::List&lt;MyItem^&gt;^ MyItemList {
  System::Collections::Generic::List&lt;MyItem^&gt;^ get() {
      <span class="synStatement">return</span> m_itemList;
  }
}
<span class="synComment">// このメソッドは「永続化すべきかどうか」つまり「初期値と違うかどうか」を返す</span>
<span class="synType">bool</span> ShouldSerializeMyItemList() {
  <span class="synStatement">return</span> m_itemList-&gt;Count &gt; <span class="synConstant">0</span>; <span class="synComment">// 空じゃなければ初期値でない</span>
}
<span class="synComment">// 「リセット」時に呼ばれるメソッド</span>
<span class="synType">void</span> ResetMyItemList() {
  m_itemList-&gt;Clear(); <span class="synComment">// 空にする</span>
}

</code></pre>

<p>
これで万事うまくいく...はずだった。しかし、肝心の「リセット」がグレーアウトされたままになっている。ここで悩むこと数時間。「ひょっとして、MyItemList に set がないからかも」と思い、次のように set を追加したら...動いてしまった。
</p>

<pre><code>
[DesignerSerializationVisibility(DesignerSerializationVisibility::Content)]
<span class="synType">property</span> System::Collections::Generic::List&lt;MyItem^&gt;^ MyItemList {
  System::Collections::Generic::List&lt;MyItem^&gt;^ get() {
      <span class="synStatement">return</span> m_itemList;
  }
  <span class="synComment">// これがないと「リセット」が有効にならない</span>
  <span class="synType">void</span> set(System::Collections::Generic::List&lt;MyItem^&gt;^ itemList) {
      <span class="synStatement">if</span> (!itemList) <span class="synComment">// 仕方がないので例外を投げることにした</span>
          <span class="synStatement">throw</span> <span class="synStatement">gcnew</span> System::Exception(<span class="synConstant">&quot;MyItemList must not be null.&quot;</span>);
      m_itemList = itemList;
  }
}
<span class="synType">bool</span> ShouldSerializeMyItemList() {
  <span class="synStatement">return</span> m_itemList-&gt;Count &gt; <span class="synConstant">0</span>;
}
<span class="synType">void</span> ResetMyItemList() {
  m_itemList-&gt;Clear();
}

</code></pre>

<p>
こういう仕様なのかどうかは分からないが、MyItemList に set が無いからという理由で ResetMyItemList が呼べないのは納得できない。ただでさえ const まわりが貧弱なのに、それに抵抗すると余計な労力を強いられるとは。ちなみに、現在の環境は Visual Studio 2008 SP1。次のバージョンでは何とかして欲しいところだが、今後 C++/CLI を使うかどうかは微妙なので、まぁどっちでもいいや。
</p>]]>
    </content>
</entry>

<entry>
    <title>C++でメンバ関数テンプレートを仮想関数にできないのは何故？</title>
    <link rel="alternate" type="text/html" href="http://zakio.net/blog/2009/03/19-214446.html" />
    <id>tag:zakio.net,2009:/blog//1.7</id>

    <published>2009-03-19T12:44:46Z</published>
    <updated>2009-03-19T18:46:35Z</updated>

    <summary>
        <![CDATA[<p>
C++ でメンバ関数テンプレートを仮想関数にしようとして、コンパイラに怒られた経験がある人は多いと思う。
</p>

<pre><code>
<span class="synType">class</span> Hoge {
<span class="synStatement">public</span>:
  <span class="synType">template</span> &lt;<span class="synType">typename</span> T&gt;
  <span class="synType">virtual</span> <span class="synType">void</span> Func(<span class="synType">const</span> T&amp; in) {} <span class="synComment">// メンバ関数テンプレートは仮想関数にできない</span>
};

</code></pre>

<p>
こういう場合、クラスを丸ごとテンプレート化してしまえば何とかなる場合が多いので、どうしてもという時は設計を見直すことになるだろう。こうすれば仮想関数でテンプレート引数の型が使えるようになる。
</p>

<pre><code>
<span class="synType">template</span> &lt;<span class="synType">typename</span> T&gt; <span class="synComment">// テンプレートクラスにすれば、仮想関数で T が使える</span>
<span class="synType">class</span> Hoge {
<span class="synStatement">public</span>:
  <span class="synType">virtual</span> <span class="synType">void</span> Func(<span class="synType">const</span> T&amp; in) {}
};

</code></pre>]]>
    </summary>
    <author>
        <name>zakio</name>
        <uri>http://zakio.net/</uri>
    </author>
    
        <category term="C++" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="c" label="C++" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="template" label="template" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="ジェネリクス" label="ジェネリクス" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="ja" xml:base="http://zakio.net/blog/">
        <![CDATA[<p>
C++ でメンバ関数テンプレートを仮想関数にしようとして、コンパイラに怒られた経験がある人は多いと思う。
</p>

<pre><code>
<span class="synType">class</span> Hoge {
<span class="synStatement">public</span>:
  <span class="synType">template</span> &lt;<span class="synType">typename</span> T&gt;
  <span class="synType">virtual</span> <span class="synType">void</span> Func(<span class="synType">const</span> T&amp; in) {} <span class="synComment">// メンバ関数テンプレートは仮想関数にできない</span>
};

</code></pre>

<p>
こういう場合、クラスを丸ごとテンプレート化してしまえば何とかなる場合が多いので、どうしてもという時は設計を見直すことになるだろう。こうすれば仮想関数でテンプレート引数の型が使えるようになる。
</p>

<pre><code>
<span class="synType">template</span> &lt;<span class="synType">typename</span> T&gt; <span class="synComment">// テンプレートクラスにすれば、仮想関数で T が使える</span>
<span class="synType">class</span> Hoge {
<span class="synStatement">public</span>:
  <span class="synType">virtual</span> <span class="synType">void</span> Func(<span class="synType">const</span> T&amp; in) {}
};

</code></pre>]]>
        <![CDATA[<p>
仮想関数ではないメンバ関数テンプレートや、テンプレートではない仮想関数は可能なのに、この2つが合わさるとダメになってしまうのは何故なのだろう。短い答えは「そういう仕様だから」だ。C++ の標準規格書には、はっきり「ダメ」と書いてある。
</p>

<blockquote>
<p>A member function template shall not be virtual. [Example:<br />
&nbsp;&nbsp;&nbsp;&nbsp;template &lt;class T&gt; struct AA {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;template &lt;class C&gt; virtual void g(C); // error<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;virtual void f(); // OK<br />
&nbsp;&nbsp;&nbsp;&nbsp;};<br />
--end example]</p><br />
<p><cite>ISO/IEC 14882:2003, 14.5.2 Member templates - 3</cite></p>
</blockquote>

<p>
でも、これで終わってしまったら面白くないので、もう少し掘り下げてみよう。何故こういう仕様になったのだろうか。テンプレートクラスが仮想メンバ関数を持てるならば、仮想テンプレートメンバ関数を許してくれても良いではないか。
</p>

<p>
色々調べてみた結果、満足のいく答えは Stroustrup 氏の著書「プログラム言語 C++ 第3版」で見つけることができた。灯台下暗しとはこのことだ。
</p>

<blockquote>
<p>メンバテンプレートは、virtual 宣言できない。たとえば次の通り。</p><br />
<p>class Shape {<br />
&nbsp;&nbsp;&nbsp;&nbsp;// ...<br />
&nbsp;&nbsp;&nbsp;&nbsp;template&lt;class T&gt; virtual bool intersect(const T&amp;) const = 0; // エラー: virtual テンプレート<br />
};</p><br />
<p>この例は、文法から逸脱しているものとして扱わなければならない。これを認めると、仮想関数を実装するために伝統的に使われてきた仮想関数テーブルテクニック（§2.5.5）が使えなくなる。誰かが新しい引数型を指定して intersect() を呼び出すたびに、リンカは Shape クラスの仮想テーブルに新しいエントリを追加しなければならなくなってしまう。</p><br />
<p><cite>プログラム言語 C++ 第3版, 13.6.2 メンバテンプレート</cite></p>
</blockquote>

<p>
なるほど、納得。全ての翻訳単位をコンパイルしてみないと、仮想関数テーブルが一意に定まらないというわけか。
</p>

<p>
ところで、何故「仕様だから」で済むような話にここまでこだわるのか。それは C# では仮想メンバ関数にジェネリクス（template のようなもの）が使えると聞いたからだ。C++ 以外の言語はサッパリなので、これを機に少し調べてみようと思ったのだが、その前に出来ない理由を明確にしておこうと思った次第。
</p>

<p>
C# はこの問題をどうやって解決しているのだろう......と、考えているうちに、なんとなく答えが分かったような気がする。C#（に限らず .NET 系全般）なら Just In Time でコンパイルしてしまえば良いではないか。無いものは作ればいい。リンカが困ったらコンパイル。たぶん、これだな。
</p>]]>
    </content>
</entry>

<entry>
    <title>Blender で favicon</title>
    <link rel="alternate" type="text/html" href="http://zakio.net/blog/2009/03/11-025236.html" />
    <id>tag:zakio.net,2009:/blog//1.8</id>

    <published>2009-03-10T17:52:36Z</published>
    <updated>2009-03-11T10:46:42Z</updated>

    <summary>
        <![CDATA[<p>
<span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="blender.png" src="http://zakio.net/blog/2009/03/blender.png" width="320" height="231" class="mt-image-left" style="float: left; margin: 0 20px 20px 0;" /></span><a href="http://www.blender.org/">Blender</a> で favicon を作ってみた。
</p>

<p>
Blender はフリーの 3DCG ソフト。操作方法にクセがありまくるため毎回イライラしながら作ることになるのだが、icon 系の画像を作る時にはナンダカンダ言いつつも結局  Blender を使っていることが多い。
</p>]]>
    </summary>
    <author>
        <name>zakio</name>
        <uri>http://zakio.net/</uri>
    </author>
    
        <category term="Blender" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="blender" label="Blender" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="favicon" label="favicon" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="ja" xml:base="http://zakio.net/blog/">
        <![CDATA[<p>
<span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="blender.png" src="http://zakio.net/blog/2009/03/blender.png" width="320" height="231" class="mt-image-left" style="float: left; margin: 0 20px 20px 0;" /></span><a href="http://www.blender.org/">Blender</a> で favicon を作ってみた。
</p>

<p>
Blender はフリーの 3DCG ソフト。操作方法にクセがありまくるため毎回イライラしながら作ることになるのだが、icon 系の画像を作る時にはナンダカンダ言いつつも結局  Blender を使っていることが多い。
</p>]]>
        <![CDATA[<p>
......と偉そうに書いているが、ちっとも使いこなせていないので質問は禁止。毎回、使うたびに初心者に逆戻りしているような状態だ。今回も、WBS+ というサイトにある<a href="http://wbs.nsf.tc/tutorial/tutorial_blender.html">「本当に初めての方のために作成したBlenderチュートリアル」</a>を参考にしながら、試行錯誤を繰り返すことになった。
</p>

<p>
favicon 程度の画像に Blender を使うのは大げさな感じがするかも知れないが、むしろ、基本的な機能だけで間に合ってしまう favicon だからこそ、全くの素人でもそれなりの画像が得られるとも言える。Blender を使えば絵の上手い下手は関係ない。物体を3次元で表現できれば、後は写真を撮る要領でイメージを切り取ってやるだけだ。
</p>

<p>
ところで、今回 favicon の画像に薬のカプセルを選んだのは、「zakio.net が悩めるエンジニアの処方箋になってくれれば」という強い思いがあった訳ではない。単にモデリングが簡単だったからだ。16 x 16 pixel では複雑なモデルを表現しきれないので、カプセル程度の単純なものの方が favicon には適していると思う。
</p>

<p>
<span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="capsule.png" src="http://zakio.net/blog/2009/03/capsule.png" width="128" height="128" class="mt-image-right" style="float: right; margin: 0 0 20px 20px;" /></span>一応、カプセルの表面に zakio.net とプリントしてはみたが、16 x 16 の favicon では、そんな細部のこだわりは全くの無意味。本物のカプセルを参考にして微妙なくぼみを付けてみたりもしたが、その部分に至っては拡大してもこの有様だ。3DCG でリアリティを出すためには細部にこだわると良いらしいが、favicon でリアリティを追求する必要はこれっぽっちもない。ここまでくると単なる自己満足の世界である。
</p>]]>
    </content>
</entry>

<entry>
    <title>値型とボックス化</title>
    <link rel="alternate" type="text/html" href="http://zakio.net/blog/2009/03/04-132423.html" />
    <id>tag:zakio.net,2009:/blog//1.5</id>

    <published>2009-03-04T04:24:23Z</published>
    <updated>2009-03-04T04:24:41Z</updated>

    <summary>
        <![CDATA[<p>
<a href="/blog/2009/02/25-215637.html">前回</a>の続き。
</p>

<p>
CLI は値型と参照型を区別する。一般に値型はスタック、参照型はヒープ上に配置されるが、C++/CLI では参照型であっても C++ と同じようにスタックに置くことができる。正確には「置いたように見せかける」だが、構文的にも意味的にもスタックに置いたオブジェクトと同じように扱える。
</p>

<pre><code>
List&lt;<span class="synType">int</span>&gt; list1; <span class="synComment">// 参照型なのにスタックに置ける（ように見える）</span>
List&lt;<span class="synType">int</span>&gt;* list2 = &amp;list1; <span class="synComment">// コンパイルエラー: CLI heap 上にあるオブジェクトはポインタで参照できない</span>
List&lt;<span class="synType">int</span>&gt;&amp; list3 = list1; <span class="synComment">// コンパイルエラー: CLI heap 上にあるオブジェクトはトラッキング参照を用いること</span>
List&lt;<span class="synType">int</span>&gt;^ list4 = %list1; <span class="synComment">// % でハンドルを取得</span>
List&lt;<span class="synType">int</span>&gt;% list5 = list1; <span class="synComment">// トラッキング参照は &amp; と同様の振る舞い</span>

</code></pre>

<p>
構文としてはスタックだが、参照型はあくまで参照型。実際のオブジェクトは CLI ヒープ上に存在するため、間接的に参照する場合はポインタではなくハンドルを使うことになる。つまり * → ^, &amp; → % のルールで自然に振舞うということ。ここまでは問題ない。混乱の元は値型だ。
</p>]]>
    </summary>
    <author>
        <name>zakio</name>
        <uri>http://zakio.net/</uri>
    </author>
    
        <category term="C++/CLI" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="c" label="C++" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="ccli" label="C++/CLI" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="ボックス化" label="ボックス化" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="値型" label="値型" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="ja" xml:base="http://zakio.net/blog/">
        <![CDATA[<p>
<a href="/blog/2009/02/25-215637.html">前回</a>の続き。
</p>

<p>
CLI は値型と参照型を区別する。一般に値型はスタック、参照型はヒープ上に配置されるが、C++/CLI では参照型であっても C++ と同じようにスタックに置くことができる。正確には「置いたように見せかける」だが、構文的にも意味的にもスタックに置いたオブジェクトと同じように扱える。
</p>

<pre><code>
List&lt;<span class="synType">int</span>&gt; list1; <span class="synComment">// 参照型なのにスタックに置ける（ように見える）</span>
List&lt;<span class="synType">int</span>&gt;* list2 = &amp;list1; <span class="synComment">// コンパイルエラー: CLI heap 上にあるオブジェクトはポインタで参照できない</span>
List&lt;<span class="synType">int</span>&gt;&amp; list3 = list1; <span class="synComment">// コンパイルエラー: CLI heap 上にあるオブジェクトはトラッキング参照を用いること</span>
List&lt;<span class="synType">int</span>&gt;^ list4 = %list1; <span class="synComment">// % でハンドルを取得</span>
List&lt;<span class="synType">int</span>&gt;% list5 = list1; <span class="synComment">// トラッキング参照は &amp; と同様の振る舞い</span>

</code></pre>

<p>
構文としてはスタックだが、参照型はあくまで参照型。実際のオブジェクトは CLI ヒープ上に存在するため、間接的に参照する場合はポインタではなくハンドルを使うことになる。つまり * → ^, &amp; → % のルールで自然に振舞うということ。ここまでは問題ない。混乱の元は値型だ。
</p>]]>
        <![CDATA[<p>
前回のエントリで、ハンドルは「CLI ヒープ用のポインタ」と述べた。CLI ヒープに確保したインスタンスをポインタで受けることはできないのだから、逆もまた然りと考えて当然である。スタックに置いた値型は CLI ヒープではなく本当にスタック上に置かれるから、ハンドルでは扱えないはずだ。
</p>

<pre><code>
<span class="synStatement">using</span> <span class="synType">namespace</span> System::Drawing;

Point pt1; <span class="synComment">// 値型をスタックに置く</span>
Point* pt2 = &amp;pt1; <span class="synComment">// 値型は CLI heap 上にないので、ポインタで参照できる</span>
Point&amp; pt3 = pt1; <span class="synComment">// &amp; も利用可</span>
Point^ pt4 = %pt1; <span class="synComment">// コンパイルエラーにならない！</span>
Point% pt5 = pt1; <span class="synComment">// コンパイルエラーにならない！</span>

</code></pre>

<p>
ハンドルでは扱えないはずだ......ったが、コンパイルエラーにはならない。どうやらこれがボックス化というもののようだ。ボックス化とは、値型のインスタンスをハンドルで扱うために、インスタンスを一旦 CLI ヒープに「暗黙に」コピーし、そのコピー先を指し示すというものだ。そんな無茶な。
</p>

<p>
それでは値を間接的に指し示すもの、ポインタとしての役割を果たしていないではないか。ボックス化によって得られたハンドルは、もはや、元のオブジェクトとは無縁の存在というわけだ。実験してみよう。
</p>

<pre><code>
Point pt(<span class="synConstant">0</span>, <span class="synConstant">0</span>); <span class="synComment">// 値型をスタック上に置く</span>
Point* pPt = &amp;pt; <span class="synComment">// ポインタで参照する</span>
Point^ hPt = %pt; <span class="synComment">// ハンドルで参照するとボックス化される</span>
pPt-&gt;X = <span class="synConstant">1</span>; <span class="synComment">// ポインタ経由で X を 1 にする</span>
hPt-&gt;Y = <span class="synConstant">2</span>; <span class="synComment">// ハンドル経由で Y を 2 にする</span>

cout &lt;&lt; <span class="synConstant">&quot;pPt = (&quot;</span> &lt;&lt; pPt-&gt;X &lt;&lt; <span class="synConstant">&quot;, &quot;</span> &lt;&lt; pPt-&gt;Y &lt;&lt; <span class="synConstant">&quot;)</span><span class="synSpecial">\n</span><span class="synConstant">&quot;</span>;
cout &lt;&lt; <span class="synConstant">&quot;hPt = (&quot;</span> &lt;&lt; hPt-&gt;X &lt;&lt; <span class="synConstant">&quot;, &quot;</span> &lt;&lt; hPt-&gt;Y &lt;&lt; <span class="synConstant">&quot;)</span><span class="synSpecial">\n</span><span class="synConstant">&quot;</span>;

<span class="synComment">// [出力結果]</span>
<span class="synComment">// pPt = (1, 0)</span>
<span class="synComment">// hPt = (0, 2)</span>

</code></pre>

<p>
確かに思ったとおりに動作している。駄目だ、ついていけない。Java とか C# とか、平気でボックス化とか言ってる言語で、この手の失敗をしないという自信が持てない。
</p>

<p>
しかも、こんな書き方もできるらしい。
</p>

<pre><code>
Point pt; <span class="synComment">// 値型をスタックに置く</span>
Point^ hPt = pt; <span class="synComment">// いきなりハンドルで受ける！！</span>

</code></pre>

<p>
C++ 的な目線で見ると、これは Point* pPt = pt; という風に見えるが、ボックス化様にそんな古い常識は通用しない。何でもアリだ。
</p>

<p>
ん、ひょっとして、new で native heap に確保したオブジェクトもボックス化様は受け入れてくれるのではないか？
</p>

<pre><code>
Point* pPt = <span class="synStatement">new</span> Point; <span class="synComment">// 値型を native heap に置く</span>
Point^ hPt = *pPt; <span class="synComment">// Point^ hPt = pt; が OK なら、これだって OK だ</span>
<span class="synStatement">delete</span> pPt;

</code></pre>

<p>
通ったぁ！ ボックス化様、万歳。...もうシラネ。
</p>

<h3>まとめ</h3>
<ul>
	<li>C++/CLI では値型にも参照型にもスタックの構文が使える</li>
	<li>スタックに置いた参照型を参照する場合は * や &amp; ではなく ^ や % を使う</li>
	<li>スタックに置いた値型を参照する場合は *, &amp;, ^, % の全てを使うことができる</li>
	<li>スタックや native heap 上のオブジェクトを ^ や % で参照すると、ボックス化によるコピーを参照するようになる</li>
</ul>]]>
    </content>
</entry>

<entry>
    <title>ハンドルとポインタと参照</title>
    <link rel="alternate" type="text/html" href="http://zakio.net/blog/2009/02/25-215637.html" />
    <id>tag:zakio.net,2009:/blog//1.4</id>

    <published>2009-02-25T12:56:37Z</published>
    <updated>2009-02-28T14:36:09Z</updated>

    <summary>
        <![CDATA[<p>
C++ に慣れ親しんだ私は、C++/CLI のハンドルを CLI heap 用のポインタという風に理解している。native heap は new で確保してポインタへ、CLI heap は gcnew で確保してハンドルへという単純な話だ。それだけならわざわざ取り上げる必要もないが、色々と調べているうちに混乱してきたので書きながら整理してみようと思う。
</p>

<p>
まずは単純な話から。
</p>

<pre><code>
<span class="synStatement">using</span> <span class="synType">namespace</span> std;
<span class="synStatement">using</span> <span class="synType">namespace</span> System::Collections::Generic;

vector&lt;<span class="synType">int</span>&gt;* pVec = <span class="synStatement">new</span> vector&lt;<span class="synType">int</span>&gt;; <span class="synComment">// native heap を new で確保して pointer で受ける</span>
List&lt;<span class="synType">int</span>&gt;^ hList = <span class="synStatement">gcnew</span> List&lt;<span class="synType">int</span>&gt;; <span class="synComment">// CLI heap を gcnew で確保して handle で受ける</span>

<span class="synComment">// -&gt; は同じ</span>
pVec-&gt;push_back(<span class="synConstant">1</span>);
hList-&gt;Add(<span class="synConstant">1</span>);

<span class="synComment">// * も同じ</span>
(*pVec).push_back(<span class="synConstant">2</span>);
(*hList).Add(<span class="synConstant">2</span>);

<span class="synComment">// delete も同じ</span>
<span class="synStatement">delete</span> pVec;
<span class="synStatement">delete</span> hList;

</code></pre>

<p>
vector に対応するものが List という点が気持ち悪いが、まぁこれはそういうもの。大事なのは new → gcnew, * → ^ という対応の部分だ。一旦領域を確保してしまえば、後は C++ と同じように扱える。
</p>]]>
    </summary>
    <author>
        <name>zakio</name>
        <uri>http://zakio.net/</uri>
    </author>
    
        <category term="C++/CLI" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="c" label="C++" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="ccli" label="C++/CLI" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="ja" xml:base="http://zakio.net/blog/">
        <![CDATA[<p>
C++ に慣れ親しんだ私は、C++/CLI のハンドルを CLI heap 用のポインタという風に理解している。native heap は new で確保してポインタへ、CLI heap は gcnew で確保してハンドルへという単純な話だ。それだけならわざわざ取り上げる必要もないが、色々と調べているうちに混乱してきたので書きながら整理してみようと思う。
</p>

<p>
まずは単純な話から。
</p>

<pre><code>
<span class="synStatement">using</span> <span class="synType">namespace</span> std;
<span class="synStatement">using</span> <span class="synType">namespace</span> System::Collections::Generic;

vector&lt;<span class="synType">int</span>&gt;* pVec = <span class="synStatement">new</span> vector&lt;<span class="synType">int</span>&gt;; <span class="synComment">// native heap を new で確保して pointer で受ける</span>
List&lt;<span class="synType">int</span>&gt;^ hList = <span class="synStatement">gcnew</span> List&lt;<span class="synType">int</span>&gt;; <span class="synComment">// CLI heap を gcnew で確保して handle で受ける</span>

<span class="synComment">// -&gt; は同じ</span>
pVec-&gt;push_back(<span class="synConstant">1</span>);
hList-&gt;Add(<span class="synConstant">1</span>);

<span class="synComment">// * も同じ</span>
(*pVec).push_back(<span class="synConstant">2</span>);
(*hList).Add(<span class="synConstant">2</span>);

<span class="synComment">// delete も同じ</span>
<span class="synStatement">delete</span> pVec;
<span class="synStatement">delete</span> hList;

</code></pre>

<p>
vector に対応するものが List という点が気持ち悪いが、まぁこれはそういうもの。大事なのは new → gcnew, * → ^ という対応の部分だ。一旦領域を確保してしまえば、後は C++ と同じように扱える。
</p>]]>
        <![CDATA[<p>
それでは参照はどうか。C++/CLI は CLI heap 用の参照としてトラッキング参照（追跡参照）というものを用意している。こちらは &amp; の代わりに % を使えばよい。
</p>

<pre><code>
vector&lt;<span class="synType">int</span>&gt;&amp; rVec = *pVec;
List&lt;<span class="synType">int</span>&gt;% tList = *hList;

cout &lt;&lt; <span class="synConstant">&quot;rVec = &quot;</span> &lt;&lt; rVec[<span class="synConstant">0</span>] &lt;&lt; <span class="synConstant">&quot;, &quot;</span> &lt;&lt; rVec[<span class="synConstant">1</span>] &lt;&lt; endl;
cout &lt;&lt; <span class="synConstant">&quot;tList = &quot;</span> &lt;&lt; tList[<span class="synConstant">0</span>] &lt;&lt; <span class="synConstant">&quot;, &quot;</span> &lt;&lt; tList[<span class="synConstant">1</span>] &lt;&lt; endl;

</code></pre>

<p>
ここまでは簡単だ。CLI heap を扱う場合は new の代わりに gcnew、* や &amp; の代わりに ^ や % を使えば、C++ と同じようにポインタや参照を扱うことが出来る。
</p>

<p>
ところで、C++ では実体からポインタを得る場合にも &amp; が用いられる。CLI heap 上の実体からハンドルを得る場合も、先ほどと同様に &amp; を % に置き換えればよい。
</p>

<pre><code>
vector&lt;<span class="synType">int</span>&gt;* pVec2 = &amp;rVec; <span class="synComment">// C++ では &amp; でポインタが得られる</span>
List&lt;<span class="synType">int</span>&gt;^ hList2 = %tList; <span class="synComment">// これに相当する演算子もやはり %</span>

cout &lt;&lt; (pVec == pVec2) &lt;&lt; endl; <span class="synComment">// pVec と pVec2 は同じものを指す</span>
cout &lt;&lt; (hList == hList2) &lt;&lt; endl; <span class="synComment">// hList と hList2 も同じものを指す</span>

</code></pre>

<p>
これはこれで納得できるような気もするが、参照はがしの時は (*hList).Add(2); のようにハンドルに対して ^ ではなく * を使っていたではないか。それに合わせるなら実体からハンドルを得る場合も % ではなく &amp; だと思うし、* → ^, & → % という対比を重視するならハンドルの参照はがしの方を * ではなく ^ にすべきだと思う。こういうズレが混乱を招くような気がするのだが、あまりそういった話を聞かないのは何故だろう。
</p>

<pre><code>
vector&lt;<span class="synType">int</span>&gt;&amp; rVec = *pVec;
List&lt;<span class="synType">int</span>&gt;% tList = *hList; <span class="synComment">// こうやって並べるとココの * が気になってくる</span>
vector&lt;<span class="synType">int</span>&gt;* pVec2 = &amp;rVec;
List&lt;<span class="synType">int</span>&gt;^ hList2 = %tList;

vector&lt;<span class="synType">int</span>&gt;&amp; rVec = *pVec;
List&lt;<span class="synType">int</span>&gt;% tList = ^hList; <span class="synComment">// * に対応する ^ で参照を剥がすか、</span>
vector&lt;<span class="synType">int</span>&gt;* pVec2 = &amp;rVec;
List&lt;<span class="synType">int</span>&gt;^ hList2 = %tList;

vector&lt;<span class="synType">int</span>&gt;&amp; rVec = *pVec;
List&lt;<span class="synType">int</span>&gt;% tList = *hList;
vector&lt;<span class="synType">int</span>&gt;* pVec2 = &amp;rVec;
List&lt;<span class="synType">int</span>&gt;^ hList2 = &amp;tList; <span class="synComment">// &amp; でハンドルを得てくれればスッキリしたのに......</span>

</code></pre>

<p>
まぁ、文句を言っても仕方がないので、これはこういうもんだと思うしかない。
</p>

<p>
次に、こんな関数を用意してみた。
</p>

<pre><code>
<span class="synType">void</span> Func1(vector&lt;<span class="synType">int</span>&gt;** ppVec) {
  *ppVec = <span class="synStatement">new</span> vector&lt;<span class="synType">int</span>&gt;(<span class="synConstant">10</span>);
}

<span class="synType">void</span> Func2(List&lt;<span class="synType">int</span>&gt;^^ hhList) {
  *hhList = <span class="synStatement">gcnew</span> List&lt;<span class="synType">int</span>&gt;(<span class="synConstant">10</span>);
}

</code></pre>

<p>
Func1 はポインタそのものを書き換えるために、ポインタへのポインタを引数としている。Func2 は Func1 の * を ^ に置き換えたもの。* → ^ というルールで全てうまくいくなら Func2 も問題ないはずだが、残念ながらこれはコンパイルエラーとなってしまう。
</p>

<pre><code>
error C3699: '^' : cannot use this indirection on type 'System::Collections::Generic::List<T> ^'

</code></pre>

<p>
<a href="http://www.ecma-international.org/publications/standards/Ecma-372.htm">C++/CLI の仕様書</a>にはそれらしい記述が見当たらなかったので、これが言語的に禁止されているかどうかは不明。ただ、ハンドルのハンドルを許してしまうと、ハンドルのハンドルのハンドルのハンドルの......ハンドルも合法となり、ガベージコレクションの時に悲惨なことになりそうな気はする。理由はともかく、<a href="http://msdn.microsoft.com/ja-jp/library/w4ctbshy(VS.80).aspx">C3699 の説明</a>には「^^ の代わりに ^% を使え」とあるので、コンパイルを通したければそれに従うしかない。^% は C++ 的には *&amp; に相当するので、これは「ハンドルそのものを参照渡ししなさい」という意味だ。「そりゃぁそうなんだけど･･････」と、モヤモヤしたまま書き直した以下のコードは（当然ながら）コンパイル可能。
</p>

<pre><code>
<span class="synType">void</span> Func1(vector&lt;<span class="synType">int</span>&gt;*&amp; pVec) {
  pVec = <span class="synStatement">new</span> vector&lt;<span class="synType">int</span>&gt;(<span class="synConstant">10</span>);
}

<span class="synType">void</span> Func2(List&lt;<span class="synType">int</span>&gt;^% hList) {
  hList = <span class="synStatement">gcnew</span> List&lt;<span class="synType">int</span>&gt;(<span class="synConstant">10</span>);
}

</code></pre>

<p>
ハンドルやトラッキング参照にスタック構文が加わると話がもう少しややこしくなるのだが、長くなってきたので別の機会に。
</p>

<h3>まとめ</h3>
<ul>
	<li>CLI heap は new ではなく gcnew で確保し、* ではなく ^（ハンドル）で受ける</li>
	<li>CLI heap 用の参照は &amp; ではなく %（トラッキング参照, 追跡参照）</li>
	<li>ポインタもハンドルも参照はがしは * だが、トラッキング参照からハンドルを得る場合は &amp; ではなく %</li>
	<li>^^（ハンドルのハンドル）は不可</li>
</ul>

<h3>参考文献</h3>
<ul>
	<li><a href="http://www.ecma-international.org/publications/standards/Ecma-372.htm">C++/CLI Language Specification, Standard ECMA-372</a></li>
</ul>]]>
    </content>
</entry>

<entry>
    <title>ソースコードを美しく</title>
    <link rel="alternate" type="text/html" href="http://zakio.net/blog/2009/02/20-015652.html" />
    <id>tag:zakio.net,2009:/blog//1.3</id>

    <published>2009-02-19T16:56:52Z</published>
    <updated>2009-02-26T06:33:52Z</updated>

    <summary>
        <![CDATA[<p>
といっても、読みやすいきれいなソースコードを書きましょうといった話ではなく、blog 上でソースコードをきれいに表示したいという話。
</p>

<p>
気になったことを備忘録の感覚で書き留めていこうという趣旨で blog を始めたのだが、気になることの大半がソフトウェアに関する事なので、ソースコードを簡単にコピペできることは「めんどくさくない」運用という点においては必須の機能。
</p>

<p>
とりあえずは、以下のようなコードが普通にコピペできれば合格だ。<br />
 <br />
<span style="color:blue;">template</span> &lt;<span style="color:blue;">typename</span> T&gt;<br />
<span style="color:blue;">class</span> Hoge {<br />
&nbsp;&nbsp;&nbsp;&nbsp;T m_val;<br />
<span style="color:blue;">public</span>:<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">explicit</span> Hoge(<span style="color:blue;">const</span> T&amp; val = T()): m_val(val) {}<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">const</span> T&amp; GetVal() <span style="color:blue;">const</span> {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">return</span> m_val; <span style="color:green;">// 持ってる値を返すだけ。意味も無くコメントを書いているのは、一行を無理やり長くするためだったりする。</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
};
</p>]]>
    </summary>
    <author>
        <name>zakio</name>
        <uri>http://zakio.net/</uri>
    </author>
    
        <category term="Movable Type" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="vimcolor" label="VimColor" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="シンタックスハイライト" label="シンタックスハイライト" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="ja" xml:base="http://zakio.net/blog/">
        <![CDATA[<p>
といっても、読みやすいきれいなソースコードを書きましょうといった話ではなく、blog 上でソースコードをきれいに表示したいという話。
</p>

<p>
気になったことを備忘録の感覚で書き留めていこうという趣旨で blog を始めたのだが、気になることの大半がソフトウェアに関する事なので、ソースコードを簡単にコピペできることは「めんどくさくない」運用という点においては必須の機能。
</p>

<p>
とりあえずは、以下のようなコードが普通にコピペできれば合格だ。<br />
 <br />
<span style="color:blue;">template</span> &lt;<span style="color:blue;">typename</span> T&gt;<br />
<span style="color:blue;">class</span> Hoge {<br />
&nbsp;&nbsp;&nbsp;&nbsp;T m_val;<br />
<span style="color:blue;">public</span>:<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">explicit</span> Hoge(<span style="color:blue;">const</span> T&amp; val = T()): m_val(val) {}<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">const</span> T&amp; GetVal() <span style="color:blue;">const</span> {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">return</span> m_val; <span style="color:green;">// 持ってる値を返すだけ。意味も無くコメントを書いているのは、一行を無理やり長くするためだったりする。</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
};
</p>]]>
        <![CDATA[<p>
HTML では一部の記号をエスケープしないといけないし、キーワードを判別して色付けしてくれる訳でもないので、当然「普通にコピペ」しただけでは上のようには表示されない。上の例はとりあえず span やら &amp;amp; やらを駆使して手作業で整形したもの。これを自動でやってくれる何かがあれば、blog を備忘録として活用できる可能性が一気に上がるというわけだ。
</p>

<h3>SyntaxHighlighter</h3>

<p>
検索で真っ先にヒットしたのが <a href="http://alexgorbatchev.com/wiki/SyntaxHighlighter">SyntaxHighlighter</a> というもの。<a href="http://alexgorbatchev.com/wiki/SyntaxHighlighter:Demo">見た感じ良さそげ</a>なので試してみようとしたのだが、Java Script で書かれているという点に引っかかってしまった。<a href="https://addons.mozilla.org/ja/firefox/addon/722">NoScript</a> を愛用している私が、ブログツールやコメントの類ならともかく、自分の blog のエントリー部分で Java Script に頼ってしまうのは何ともいえない矛盾を感じる。Java Script を OFF にしていればシンタックスハイライト無しの pre タグとして見えるような気がするので、もしそうなら許容範囲に収まっているかも知れないが、とりあえず保留。
</p>

<h3>VimColor</h3>

<p>
次に見つかったのが <a href="http://blog.drry.jp/2005/12/16/1855">VimColor プラグイン</a>というもの。これは Movable Type 用のプラグインなので、サーバ側で整形処理が完結する。よし、これだ。
</p>

<pre><code>
<span class="synType">template</span> &lt;<span class="synType">typename</span> T&gt;
<span class="synType">class</span> Hoge {
  T m_val;
<span class="synStatement">public</span>:
  <span class="synType">explicit</span> Hoge(<span class="synType">const</span> T&amp; val = T()): m_val(val) {}
  <span class="synType">const</span> T&amp; GetVal() <span class="synType">const</span> {
      <span class="synStatement">return</span> m_val; <span class="synComment">// 持ってる値を返すだけ。意味も無くコメントを書いているのは、一行を無理やり長くするためだったりする。</span>
  }
};

</code></pre>

<p>
最初のインデントがおかしいけど、概ね良好。うん、悪くないね。
</p>

<p>
......と、簡単に導入しているように見えるが、root 権限の無いレンタルサーバ上に Perl のモジュールやら vim やら（！）をインストールするのは大変な作業だった。そもそも「CPAN って何？」状態だったし、PuTTY を使ったのも初めて。
</p>

<p>
以下、参考にしたもの。
</p>

<ul>
  <li><a href="http://i-am.web777.net/2006/12/vimcolor.html">vimcolor プラグイン</a></li>
  <li><a href="http://iandeth.dyndns.org/mt/ian/archives/000623.html">一般ユーザ環境におけるCPANモジュールの使い方</a></li>
  <li><a href="http://www.hazama.nu/t2o2/archives/002696.html">さくらインターネットの共用サーバに vim をインストールする</a></li>
</ul>

<p>
また、<a href="http://wo.skr.jp/mt/2005/11/cpan.html">ここ</a>のコメント欄にあるように、SetEnv できない環境下で CGI からローカルモジュールを使う場合は use lib が必要。そのため、プラグインの頭の部分を以下のように修正して Text::VimColor モジュールのインストール先を指定する。
</p>

<pre><code>
<span class="synPreProc">use strict</span>;
<span class="synPreProc">use </span>MT;
<span class="synPreProc">use </span>MT::Template::Context;
<span class="synPreProc">use lib</span> <span class="synConstant">'/home/*****/perl/lib/perl5/site_perl'</span>;
<span class="synPreProc">use </span>Text::VimColor;

</code></pre>

<p>
私のように vim を自前でインストールした場合は、Text::VimColor にもその場所を教えてあげないといけない。
</p>

<pre><code>
<span class="synStatement">my</span> <span class="synIdentifier">$vimcolor</span> = Text::VimColor-&gt;<span class="synStatement">new</span>(<span class="synConstant">vim_command </span>=&gt; <span class="synConstant">'/home/*****/local/bin/vim'</span>, <span class="synConstant">vim_options </span>=&gt; <span class="synIdentifier">\@options</span>);

</code></pre>

<p>
また、そのままだとエラーになるので、options に -T xterm を追加する。この問題の解決には <a href="http://www.perlmonks.org/?node_id=605626">Text::VimColor in a CGI - possible?</a> が役立った。ついでに、さりげなく tabstop を 4 にしている。
</p>

<pre><code>
<span class="synStatement">my</span> <span class="synIdentifier">@options</span> = (<span class="synConstant">qw( -XZ -i NONE -u NONE -N -T xterm )</span>,
  <span class="synConstant">'+set nomodeline'</span>,
  <span class="synConstant">'+set expandtab'</span>,
  <span class="synConstant">'+set tabstop=4'</span>,
  <span class="synConstant">'+set encoding='</span> . MT::ConfigMgr-&gt;instance()-&gt;PublishCharset);

</code></pre>

<p>
ちなみに、MTEntryBody だけでなく MTEntryMore の方にも vim_color = "none" としておかないと、「続き」側で編集した内容に VimColor が適用されない。まぁ、このあたりは特に何も書かなくても気づくとは思うが、念のため。
</p>

<pre><code>
<span class="synIdentifier">&lt;$MTEntryMore vim_color=</span><span class="synConstant">&quot;none&quot;</span><span class="synIdentifier">$&gt;</span>

</code></pre>

<p>
それにしても、プラグインの導入記事にプラグイン自身が活躍するところが面白い。いい感じに続けられそうな気がするぞ。
</p>]]>
    </content>
</entry>

<entry>
    <title>blog あるいは備忘録</title>
    <link rel="alternate" type="text/html" href="http://zakio.net/blog/2009/02/14-215530.html" />
    <id>tag:zakio.net,2009:/blog//1.1</id>

    <published>2009-02-14T12:55:30Z</published>
    <updated>2009-02-26T06:35:52Z</updated>

    <summary>
        <![CDATA[<p>とりあえずテスト。</p>

<p>こんなイイ加減なエントリーで始まるブログも珍しいと思うが、極度に飽きっぽい私にとっては、これくらいから始めた方が長続きするはず。</p>

<p>最近（に限った話ではないかも知れないが）物忘れが激しくなってきた気がするので、気になったことは記録しておいた方がいいかも、というのがブログを始めようと思った動機。ただし、記録という作業そのものに手間がかかってしまうとあっという間に終了フラグが立ってしまう。</p>

<p>そこで、ブログ界のデファクトスタンダードである（らしい） Movable Type を導入し、このあたりの「めんどくささ」を取り除いてみようという試みだが、果たしてうまくいくことやら......。</p>]]>
    </summary>
    <author>
        <name>zakio</name>
        <uri>http://zakio.net/</uri>
    </author>
    
        <category term="Movable Type" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="movabletype" label="Movable Type" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="ja" xml:base="http://zakio.net/blog/">
        <![CDATA[<p>とりあえずテスト。</p>

<p>こんなイイ加減なエントリーで始まるブログも珍しいと思うが、極度に飽きっぽい私にとっては、これくらいから始めた方が長続きするはず。</p>

<p>最近（に限った話ではないかも知れないが）物忘れが激しくなってきた気がするので、気になったことは記録しておいた方がいいかも、というのがブログを始めようと思った動機。ただし、記録という作業そのものに手間がかかってしまうとあっという間に終了フラグが立ってしまう。</p>

<p>そこで、ブログ界のデファクトスタンダードである（らしい） Movable Type を導入し、このあたりの「めんどくささ」を取り除いてみようという試みだが、果たしてうまくいくことやら......。</p>]]>
        
    </content>
</entry>

</feed>

