/// std::bind* と std::mem_fun* の強化版。
/**
 * refer to refer 問題が解決したのと、
 * ptr_fun が不要なのがウリ。
 */

#include <boost/functional.hpp>

#include <functional>
#include <algorithm>
#include <vector>

// まあエラーが見たければ外して下さい。
// #define WATCH_ERROR

class Class {
public:
	void func1(int i) {}
	void func2(Class& c) {}
};

void func(int i, int j) {}

void checkReferToRefer() {
	std::vector<Class*> cs;
	Class c;

	// これは大丈夫です。
	std::for_each(cs.begin(), cs.end(),
				  std::bind2nd(std::mem_fun(&Class::func1), 1));
	// refer to refer!
#ifdef WATCH_ERROR
	std::for_each(cs.begin(), cs.end(),
				  std::bind2nd(std::mem_fun(&Class::func2), c));
#endif

	// これは当然大丈夫です。
	std::for_each(cs.begin(), cs.end(),
				  boost::bind2nd(boost::mem_fun(&Class::func1), 1));
	// refer to refer 関係無し。
	std::for_each(cs.begin(), cs.end(),
				  boost::bind2nd(boost::mem_fun(&Class::func2), c));

}

void checkPtrFun() {
	std::vector<int> is;

#ifdef WATCH_ERROR
	// これは、ダメで、
	std::for_each(is.begin(), is.end(), std::bind2nd(&func, 1));
#else
	// こうしなければならない。
	std::for_each(is.begin(), is.end(),
				  std::bind2nd(std::ptr_fun(&func), 1));
#endif

	std::for_each(is.begin(), is.end(), boost::bind2nd(&func, 1));
}

int main() {
	checkReferToRefer();
	checkPtrFun();
}


