とくにあぶなくないRiSKのブログ

危ないRiSKのブログだったかもしれない。本当はRiSKだけどググラビリティとか取得できるIDの都合でsscriskも使ったり。

非スマートポインタを返す不届き者関数をラップしよう

非スマートポインタ(別名:生ポインタ)を返し、プログラマstd::freeを書かせるような関数がこの世には存在します。 そのような関数は危なすぎるので、安全かつ楽にどうにかしたいところ。ラップしてみましょう。これでC由来の関数はおおよそラップできそうです。

ここではstd::mallocを例にコードを示します。

// library

#include<functional>
#include<memory>

template<class R, class... ArgTypes, class D>
std::function<std::shared_ptr<R>(ArgTypes...)> to_safe_function(R* func(ArgTypes...), D d){
 return [func, d](ArgTypes... at)->std::shared_ptr<R>{
  return std::shared_ptr<R>(func(at...), d);
 };
}


// user

#include<cstdlib>

auto const safe_malloc = to_safe_function(std::malloc, std::free);

int main(){
 {
  auto stupid_pointer = std::malloc(1);
  std::free(stupid_pointer);
 }
 {
  auto smart_pointer = safe_malloc(1);
 }
}

しかし時間と能力の都合でジェネリック度が足りないです。どなたかに改善してほしいなぁ。

  • 関数は渡せるが、関数っぽい物(callable type)を渡せない
  • 元の関数の返却値の型がポインタ固定。
  • 返却値の型がstd::shared_ptr固定。std::unique_ptrも他のスマポも使いたいよね。
  • std::shared_ptrに削除子(deleter)が指定できない。指定したいよね。 (こっそりコード修正)