Move semantics に対応した Boost.Containersを試す

id:melponさんに教えて頂いた
Boost.Containers
を軽く試します。

Boost.Containerライブラリは、STLコンテナを含むいくつかの有名なコンテナを実装します。
このライブラリの目標は、標準コンテナにないもの、あるいはC++03のコンパイラで最新の標準ドラフトの機能を提供することです。

Boostの一部ではないのでダウンロードしてきます。
どうもBOOST_MOVABLE_BUT_NOT_COPYABLEのような事を書く必要があるようです。

#include <boost/container/vector.hpp>
#include <boost/move/move.hpp>

struct Hoge
{
	BOOST_MOVABLE_BUT_NOT_COPYABLE(Hoge)
public:
	Hoge(){
		cout << "Hoge::Hoge" << endl;
	}
	virtual ~Hoge(){
		cout << "Hoge::~Hoge" << endl;
	}
	Hoge(BOOST_RV_REF(Hoge)) {
		cout << "Hoge::Hoge(const Hoge& rhs)" << endl;
	}
	Hoge& operator=(BOOST_RV_REF(Hoge)) {
		cout << "Hoge::operator=(const Hoge& rhs)" << endl;
		return *this;
	}
};

int main()
{
	typedef boost::container::vector<Hoge> BoostVectorHoge;
	typedef BoostVectorHoge::iterator BoostVectorHogeIt;
	
	BoostVectorHoge hv;
	Hoge hoge1;
	Hoge hoge2;
	
	cout << "hv push_back:1" << endl;
	hv.push_back(boost::move(hoge1));
	
	cout << "hv push_back:2" << endl;
	hv.push_back(boost::move(hoge2));
	
	cout << "hv reserve:100" << endl;
	hv.reserve(100);
	
	cout << "hv reserve:200" << endl;
	hv.reserve(200);
	
	BoostVectorHoge hv_other(boost::move(hv));
	
	cout << "hv_other size:" << hv_other.size() << endl;
	cout << "hv_other capa:" << hv_other.capacity() << endl;
	
	cout << "hv size:" << hv.size() << endl;
	cout << "hv capa:" << hv.capacity() << endl;
	cout << "hv empty:" << hv.empty() << endl;
}

結果。
おろ、どうもreserveでコピーが発生しているような気がする。


むむ?
ただ、BoostVectorHoge hv_other(boost::move(hv));は大丈夫。
ちゃんとコンテナは移動している。(sizeとcapacityは移動している)


hv.push_back(boost::move(hoge1));
も同じように機能する事を期待しているんだけど、使い方が間違っているのかな?
いや、移動だから正しいのか?

(resize時の動作を含めてMove Semanticsに対応していないvectorとの実行結果を調べて追記する予定)

Hoge::Hoge
Hoge::Hoge
hv push_back:1
Hoge::Hoge(const Hoge& rhs)
hv push_back:2
Hoge::Hoge(const Hoge& rhs)
Hoge::Hoge(const Hoge& rhs)
Hoge::~Hoge
hv reserve:100
Hoge::Hoge(const Hoge& rhs)
Hoge::Hoge(const Hoge& rhs)
Hoge::~Hoge
Hoge::~Hoge
hv reserve:200
Hoge::Hoge(const Hoge& rhs)
Hoge::Hoge(const Hoge& rhs)
Hoge::~Hoge
Hoge::~Hoge
hv_other size:2
hv_other capa:200
hv size:0
hv capa:0
hv empty:1
Hoge::~Hoge
Hoge::~Hoge
Hoge::~Hoge
Hoge::~Hoge