2007年10月12日金曜日

"基底クラスからの派生クラスのメソッドの呼び出し" と CRTP

まずはコード。

template<class Derived>
class Base {
public:
  void Process() {
// 派生クラスのメソッド呼び出し
static_cast<Derived*>(this)->SubProcess();
  }
};

class Hoge : public Base<Hoge> {
public:
  void SubProcess() {
    std::cout << "Hoge!" << std::endl;
 }
};

派生クラスに実装した処理を基底クラスから呼び出してます。
普通なら、SubProcessメソッドはvirtualにしてBaseクラスに定義しておくところですが、virtualにするとメソッドの呼び出しに多少なりともコストがかかってしまいます。
そのコストを避けるためのカギがCRTP (Curiously Recurring Template Pattern)です。
CRTPを使えば呼び出すメソッドが静的に決まるので、うまくいけばメソッドがインライン展開されて呼び出しコストがゼロになる可能性も期待できます。

virtualにする方が一般的でわかりやすいですが、ここぞという所で使えば威力を発揮してくれそうなイディオムです。

2007年10月3日水曜日

テンプレートクラスにネストされたテンプレートクラスのテンプレートメソッド

テンプレートクラスにネストされた、テンプレートクラスのテンプレートメソッドの実装を
クラスの定義と切り離してみました。

Before:

template<class T>
struct Hoge
{
  template<class U>
  struct NestedHoge
  {
    template<class V>
    void Process()
    {
      std::cout << "Hoge Hoge!!" << std::endl;
    }
  };
};


After:
template<class T>
struct Hoge
{
  template<class U>
  struct NestedHoge
  {
    template<class V>
    void Process();
  };
};

template<class T>
template<class U>
template<class V>
inline void Hoge<T>::NestedHoge<U>::Process()
{
  std::cout << "Hoge Hoge!!" << std::endl;
}


えぐい。。。

2007年9月20日木曜日

シフト命令で割り算の落とし穴

整数を2のべき乗で割り算したいとき、割り算の代わりに右算術シフトを使うことがあります。
特に割り算の処理コストが無視できないときにはよく右算術シフトを利用します。

が、今日1つ落とし穴があることに気付きました。

(-1) >> 1


が0になってくれません。

当然といえば当然ですね。0xFFFFFFFF はどれだけ右算術シフトしても 0xFFFFFFFF です。。。

見事にはまってしまいました。

2007年7月24日火曜日

A Lock-Free Hash Table

Google TeckTalksで見つけた、Lock-FreeなHash Tableのビデオ。



まだみてません。

How To Design A Good API and Why it Matters

Google TeckTalks でみつけたAPIデザインに関するビデオ。



もう少しゆっくり喋ってもらえるとありがたいなぁ。。

PDFも発見。

2007年2月23日金曜日

templateクラスでMFCのメッセージ処理

templateクラスでMFCのメッセージハンドラを使おうと思ったんですが、肝心のBEGIN_MESSAGE_MAPが書けない!

と思って調べてみたら色々出てきました。

MSDNのもヒットして、ちゃんとMSDNにも載ってるんだなーと思って読んでいたら、
VC8でちゃっかりBEGIN_TEMPLATE_MESSAGE_MAPなるマクロが追加されているではないですか!
やるなぁ。ありがたく使わせて頂きます。

How to: Create a Message Map for a Template Class

2007年2月19日月曜日

std::auto_ptrの新たな罠(VC8)

VC8では以下のコードがあっさりコンパイルされるようです。

std::auto_ptr<int> p(new char);


これのせいでバッファオーバーフローに半日悩まされました。どう考えても罠です!親切でもなんでもないです。キャストしたかったら自分でします!
boost::shared_ptr使うほどでもないかなというケースでstd::auto_ptr使っていましたがそれすらやめたほうがよさそうですね。。

ちなみに、VC7.1でもgcc 3.4.4でも確認してみましたが、コンパイルエラーになりました。
そりゃ普通そうですよね。

  © Blogger template 'Isolation' by Ourblogtemplates.com 2008

Back to TOP