boost::tokenizerを使うときの注意。
以下のクラスを作って、文字列のパースした状態を保存しておきたいと思った際に、
うっかりtokenizerに渡す文字列は、shared_ptr管理かメンバ変数で持たせるかの
いずれかにしておかないと大変な事になります。
というのも
tok = boost::shared_ptr< CsvTok >( new CsvTok( data_ , *sep ) );
ここで渡されたdata_(文字列)情報は、コピーされず、begin(),end()で取得されてしまうので、
関数を抜けると不定になるのです。
class CsvParser { public: typedef boost::char_separator< char > CsvSep; typedef boost::tokenizer< CsvSep > CsvTok; private: boost::shared_ptr< CsvTok > tok; boost::shared_ptr< CsvSep > sep; std::string data_; public: CsvParser(); bool Split( __in std::string str ); const CsvParser::CsvTok& Tokens( void ) const { return *tok; } };
CsvParser::CsvParser() { } bool CsvParser::Split( __in std::string str ) { sep = boost::shared_ptr< CsvSep >( new CsvSep(",") ); data_ = str; // トークンを分割する tok = boost::shared_ptr< CsvTok >( new CsvTok( data_ , *sep ) ); ASSERT( tok.get()!=NULL ); return true; }