読者です 読者をやめる 読者になる 読者になる

boost::logはmutable_constantをshallowコピーする

C++ Boost

boost::logのloggerとそれに紐付いたmutable_constantをコピーしようとしてハマったのでメモ。
deepコピーがしたかったのだけど、結果はタイトル通りshallowコピーだった。ドキュメントにもよく読んだら書いてあった。

The shared pimpl design comes significant in a few cases though. One such case is copying the attribute. The copy operation is shallow, so multiple interface objects may refer to a single implementation object. There is no way to deep copy an attribute.

http://www.boost.org/doc/libs/1_57_0/libs/log/doc/html/log/detailed/attributes.html

clone()とかあれば便利なんだけどなさそうだし、どうしてもしたければ自前でmutable_constantを再生成して登録するぐらいしかないのかな・・・

テストコード

#include <iostream>
#include <boost/log/sources/logger.hpp>
#include <boost/log/attributes/mutable_constant.hpp>
using namespace std;
namespace lg = boost::log;

int main(int argc, char* argv[]) {
	//このmutable_constantをコピーすると内部変数はどうなるのか?
	lg::attributes::mutable_constant<int> attr1(1);
	cout << attr1.get() << endl;

	//mutable_constantのコピーは内部変数をshallowコピーする
	lg::attributes::mutable_constant<int> attr2(0);
	attr2 = attr1;
	attr2.set(2);
	cout << attr1.get() << " " << attr2.get() << endl;

	//mutable_constantをloggerに登録
	lg::sources::logger log1;
	log1.add_attribute("attr", attr1);

	//loggerのコピーは保持するmutable_constantをshallowコピーする
	lg::sources::logger log2;
	log2 = log1;
	lg::attributes::mutable_constant<int> attr3 = lg::attribute_cast<lg::attributes::mutable_constant<int>>(log2.get_attributes().find("attr")->second);
	attr3.set(3);
	cout << attr1.get() << " " << attr2.get() << " " << attr3.get() << endl;

	return 0;
}

実行結果

1
2 2
3 3 3