`

C++11应用:占位模式

 
阅读更多

    有人称为命令模式,好比先定义了一个命令(行为+参数),然后把这个命令,加入到排队、传递等策略中,等到合适的时机再操作执行。而我觉得更像机器学习中的placeholder占位模式,把函数的地址和传入参数都绑定了,再手动操作执行:

#include <functional>
#include <type_traits>

template <typename R=void>
struct CommCommand
{
private:
	std::function<R()> m_f;
public:

	// 接受可以调用对象的函数封包器
	template <class F, class... Args, class=typename std::enable_if<!std::is_member_function_pointer<F>::value>::type>
	void Wrap(F&& f, Args&&... args)
	{
		m_f = [&] {return f(args...); };
	}

	// 接受常量成员函数的封包器
	template <class R, class C, class... DArgs, class P, class... Args>
	void Wrap(R(C::*f)(DArgs...) const, P&& p, Args&&... args)
	{
		m_f = [&, f] {return (*p.*f)(args...); };
	}

	// 接受非常量成员函数的函数包装器
	template <class R, class C, class... DArgs, class P, class... Args>
	void Wrap(R(C::*f)(DArgs...), P&& p, Args&&... args)
	{
		m_f = [&, f] {return (*p.*f)(args...); };
	}

	R Execute() 
	{
		return m_f();
	}
};

struct STA
{
	int m_a;
	int operator()()
	{
		return m_a;
	}
	int operator()(int n)
	{
		return m_a + n;
	}
	int triple0() 
	{
		return m_a * 3;
	}
	int triple(int a)
	{
		return m_a * 3 + a;
	}
	int triple1() const
	{
		return m_a * 3;
	}
	const int triple2(int a) const
	{
		return m_a * 3 + a;
	}
	void triple3()
	{
		cout << "triple3" << endl;
	}
	
};
int add_one(int n)
{
	cout << "add_one" << endl;
	return n + 1;
}
void printTest()
{
	cout << "printTest" << endl;
}

void test()
{
	CommCommand<int> cmd;
	// 普通函数
	cmd.Wrap(add_one, 0);
	// lambda表达式
	cmd.Wrap([](int n) {return n + 1; }, 2);
	// 接受函数对象
	typedef int(*Fun)(int);
	Fun f = add_one;
	cmd.Wrap(f, 5);

	STA t = { 10 };
	int x = 3;
	// 接受成员函数
	cmd.Wrap(&STA::triple0, &t);
	cmd.Wrap(&STA::triple, &t, x);
	cmd.Wrap(&STA::triple, &t, 3);
	cmd.Wrap(&STA::triple2, &t, x);
	
	auto r = cmd.Execute();

	cout << "result:" << r << endl;

	CommCommand<void> cmd1;
	cmd1.Wrap(&STA::triple3, &t);
        cmd1.Wrap(printTest);
	cmd1.Execute();
}
int main(int, char *[])
{     
	test();  
	 
	system("pause");
	return 0;
}

 

   另外一种实现:

template <typename Receiver>
class Command 
{

public:
	typedef void(Receiver::*Action)();
	Command(Receiver* r, Action a):_receiver(r), _action(a) {}
	virtual void Execute();
protected:
	Action _action;
	Receiver* _receiver;
};

template <typename Receiver> 
void Command<Receiver>::Execute() // 等同实现SimpleCommand子类
{
	(_receiver->*_action)(); // 可以使用Command中private变量
}

template <typename Receiver>
class SimpleCommand :Command<Receiver>
{
public:  
	SimpleCommand(Receiver* r, Action a) :Command<Receiver>(r, a) {} 

	void Execute() {
		(_receiver->*_action)();  // 不能使用Command中private变量
	}
};


class MyClass
{
public:
	void print()
	{
		cout << "MyClass print..." << endl;
	}
};

void test() { 
	MyClass* receiver = new MyClass;

	Command<MyClass>* cmd = new Command<MyClass>(receiver, &MyClass::print);
	cmd->Execute();

	SimpleCommand<MyClass>* simpleCommand = new SimpleCommand<MyClass>(receiver, &MyClass::print);
	simpleCommand->Execute();
 
}
 

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics