2007年10月31日水曜日

関数の戻り値で配列の参照を返す(C++)

int型の配列へのconst参照を返す関数

const int (&GetArray())[4] {
 const static int s_array[4] = {1, 2, 3, 4};
 return s_array;
}

はっきり言って、読めません。関数名の後に配列の長さがあったりとか。。。

普通こういう場合はポインタを返すように書くと思いますが、型から「配列の長さ」の情報が失われてしまうという欠点があります。
どうしても戻り値の型に「配列の長さ」を残しておきたいという場合は使えます。

参照元

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でも確認してみましたが、コンパイルエラーになりました。
そりゃ普通そうですよね。

2007年1月29日月曜日

FreeBSDハードディスク交換

FreeBSD環境のハードディスクを交換する際に、古いディスクの内容をまるごと新しいディスクに移す際の手順。

1. 古いHDDをプライマリ、新しいHDDをセカンダリに接続して起動

2. 古いHDDに新しいディスクのマウント先ディレクトリを作成しておく。(スライスの構成と同じだけ)

mkdir /mnt
mkdir /mnt/var
mkdir /mnt/tmp
mkdir /mnt/usr


2. 古いHDDと同じような構成で、新しいHDDのパーティションを切る。
sysinstall -> Fdisk

3. 古いHDDと同じような構成で、新しいHDDのスライスを設定する。
マウント先は先ほど作成したディレクトリ。
sysinstall -> label

4. 各スライスをコピーする
dump -0af - -C 32 / | ( cd /mnt ; restore xf - )
dump -0af - -C 32 /var | ( cd /mnt/var ; restore xf - )
dump -0af - -C 32 /tmp | ( cd /mnt/tmp ; restore xf - )
dump -0af - -C 32 /usr | ( cd /mnt/usr ; restore xf - )



参照:FreeBSD QandA 1859

2007年1月24日水曜日

VisualStudio2005 cppとhファイルの切り替え

VisualStudio 2005でcppファイルとhファイルを切り替えるためのマクロ

参照 BorisJ's Blog

2007年1月17日水曜日

数値解析ソフト

FreeMat
Octave
Scilab

  © Blogger template 'Isolation' by Ourblogtemplates.com 2008

Back to TOP