2013年3月9日土曜日

本日のバグ lambda

本日のバグ。今回は、boost::shared_ptr と boost::weak_ptr にまつわる話です。
集合セット S に foo クラスが入っており、集合セット S は生成と破棄を行います。
集合セット S に含まれる foo は、それぞれ異なりますが、重複する場合があります。
foo を shared_ptr でラップして、集合セットに保持し、全体としての foo のカタログを weak_ptr で持たそうかなぁ?とも思いましたが、カタログにアクセスする度に weak_ptr::lock を呼び出すのも非効率的です。何よりも、foo オブジェクトを探したいのに死んでいたら foo オブジェクトの値を取り出せないので、lower_bound とかで検索できないのも痛いです。
という事で、shared_ptr::use_count を調べて、カタログ以外に所有者がいなければ、消せばええやん!という風にしましたが、うまく行きませんでした。以下のコードです。
#include <iostream>
#include <vector>
#include <boost/shared_ptr.hpp>
#include <boost/range/algorithm_ext/erase.hpp>

struct foo {
};

typedef boost::shared_ptr<foo>  foo_t;

int main()
{
  std::vector<foo_t>  v;
  for( int i = 0; i < 10; ++i )  v.push_back( foo_t( new foo ) );
  std::cout << "=== run remove_erase_if" << std::endl;
  boost::remove_erase_if( v, 
    [](foo_t val) -> bool {
     std::cout << val.use_count() << std::endl;
      return val.use_count() <= 1;
    }
  );
  std::cout << "erased -> " << v.size() << std::endl;
  
  return 0;
}
はい、正解は、
   [](foo_t& val) -> bool {
参照でアクセスしないと、カウント増えますよねwwwwwって事でした。

0 件のコメント: