ゆとりーなの日記

日記的な事を書いて行くと思はれる

COMったちゃん

DirectXはCOMったちゃんなので、大抵はIUnknownを継承している訳です。よって解放にはRelseaseを使うことになる訳です。これをstd::unique_ptrで扱いうにはカスタムデリータを書いてやるわけですが、特殊化の方向で行くと痛い目にあうみたいです。

namespace std {
template <>
struct std::default_delete<IUnknown> {
  void operator ()(IUnknown * const com) {
    com->Release();
  }
};
}

int main() {
  std::unique_ptr<IDirect3D9> direct3d(Direct3DCreate9(D3D_SDK_VERSION));
  return 0;
}

はい。このコードはmainを抜けるときにこけます。どうやらIDirect3D9はIUnknownを継承してるよと声高に主張したところで上の特殊化は呼ばれないみたいです。
大人しく

namespace std {
template <>
struct std::default_delete<IUnknown> {
  void operator ()(IUnknown * const com) {
    com->Release();
  }
};
}

int main() {
  std::unique_ptr<IDirect3D9, std::default_delete<IUnknown>> direct3d(Direct3DCreate9(D3D_SDK_VERSION));
  return 0;
}

と明示的にカスタムデリータを指定してやると落ちなくなります。ここまでやるならわざわざ特殊化の形を取らないでもよかったかな感が漂います。