| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
 100
 101
 102
 
 | #include <functional>
#include <iostream>
#include <string>
#include <map>
#include <memory>
 
class FctBase;
 
template <class Ret, class... Args>
class Fct;
 
class FctBase {
 
	// oui c'est sale :/
	virtual void virtualFctPourDynamicCast() { }
 
public:
	template<class Ret, class... Args>
	Ret doJob(Args... args) const {
		const Fct<Ret, Args...> *_this = dynamic_cast<const Fct<Ret, Args...>*>(this);
		if(!_this) {
			throw std::exception();
		}
 
		return _this->call(args...);
	}	
};
 
template <class Ret, class... Args>
class Fct: public FctBase {
 
	const std::function<Ret(Args...)> m_fct;
 
public:
 
	Fct(const std::function<Ret(Args...)> fct):
		m_fct(fct)
	{ }
 
	~Fct() { }
 
	Ret call(Args... args) const {
		return m_fct(args...);
	};
 
};
 
 
template <class Ret, class... Args>
Ret call(const Fct<Ret, Args...> *fct, Args... args) {
	return fct->call(args...);
} 
 
int main(int argc, char** argv) {
 
	typedef std::unique_ptr<FctBase> ptr;
 
	std::map<std::string, ptr> fctMap;
 
	auto fct1 = [](int i, int j)->int { return i+j; };
	auto fct2 = [](char c)->float { return c/255.f; };
 
	// insert
	fctMap.insert(std::make_pair("fct1", ptr(new Fct<int, int, int>(fct1))));
	fctMap.insert(std::make_pair("fct2", ptr(new Fct<float, char>(fct2))));
 
	// recherche et exec si trouvé	
	auto itFct1 = fctMap.find("fct1");
	if(itFct1 != fctMap.end()) {
		try {
			int ret = itFct1->second->doJob<int, int, int>(1, 2);
			std::cout << "fct1(1, 2) = " << ret << std::endl;
		}
		catch(...) {
			std::cout << "fct1(1, 2) fail\n";
		}		
	}
 
	auto itFct2 = fctMap.find("fct2");
	if(itFct2 != fctMap.end()) {
		try {
			float ret = itFct2->second->doJob<float, char>('h');
			std::cout << "fct2('h') = " << ret << std::endl;
		}
		catch(...) {
			std::cout << "fct2('h') fail\n";
		}
	}
 
	// mauvais appel
	if(itFct1 != fctMap.end()) {
		try {
			int ret = itFct1->second->doJob<int, char>('h');
			std::cout << "fct1('h') = " << ret << std::endl;
		}
		catch(...) {
			std::cout << "fct1('h') fail\n";
		}
	}
 
	return 0;
} | 
Partager