T*集合 => T const*集合 の変換にptr_vectorを使う


ポインタの集合をconstポインタの集合に渡す

について.


元記事コメント欄に書いてあったptr_vectorのアロケータの指定をしてみたらあっさり出来た話.
コード全体
=> 前半https://ideone.com/nSs69
=> 後半(ポインタとして比較)https://ideone.com/ESkBz

問題

引用元で論じている問題は,
普通のコンテナにポインタを格納すると, 余計なデリファレンスが必要になって
const(_iterator) の扱いがうまくいかないこと.

Boostで解決

ところでBoostにはポインタを格納する専用のコンテナが用意されているので, 使ったらいいよ!

実際のコード

要点だけ抜き出すと

Hoge h[3];
boost::ptr_vector<
	Hoge, boost::view_clone_allocator
> xs(&h[0], &h[3]); // 構築

// 各々の指しているオブジェクトの任意の関数が呼び出せる
void multiProcM(ptr_vector<Hoge, view_clone_allocator>::iterator b,
				ptr_vector<Hoge, view_clone_allocator>::iterator e);

// 各々の指しているオブジェクトのconst関数が呼び出せる
void multiProcC(ptr_vector<Hoge, view_clone_allocator>::const_iterator b,
                ptr_vector<Hoge, view_clone_allocator>::const_iterator e);

// ポインタとして比較
struct ptr_cmp {
	bool operator() (int const & lhs, int const & rhs) const {
		return &lhs < &rhs;
	}
};
std::set_difference(v1.begin(), v1.end(), ib, ie
		, boost::ptr_container::ptr_back_inserter(v4), ptr_cmp);

まとめなど

  • Boostすごい
  • 元記事ではイテレータを賢くして解決しているので, Boostに用意されているポインタコンテナでは不十分な場合にも対応できるかも知れない
  • ptr_vectorはlist_ofから構築しようとしたらエラーになったけどなぜだろう
  • set_differenceのデフォルトのcomparatorを使うと値の比較になってしまうので注意
  • Boostすごい