Если вы можете использовать C ++ 0x и шаблоны variadic, вы можете достичь этого, используя комбинацию std::function
, std::bind
и совершенную пересылку:
#include <iostream>
#include <functional>
template <typename Result = void>
class instruction
{
public:
template <typename Func, typename... Args>
instruction(Func func, Args&&... args)
{
m_func = std::bind(func, std::forward<Args>(args)...);
}
Result execute()
{
return m_func();
}
private:
std::function<Result ()> m_func;
};
double add(double a, double b)
{
return (a + b);
}
int main()
{
instruction<double> test(&add, 1.5, 2.0);
std::cout << "result: " << test.execute() << std::endl;
}
Пример с выводом: http://ideone.com/9HYWo
В C ++ 98/03, к сожалению, вам придется перегружать конструктор для N-параметров самостоятельно, если вам нужно поддерживать переменное число аргументов. Вы также использовали бы boost::function
и boost::bind
вместо std::
эквивалентов. Кроме того, существует проблема проблема пересылки , поэтому для идеальной пересылки вам потребуется экспоненциальное количество перегрузок в зависимости от количества аргументов, которые необходимо поддерживать. Boost имеет библиотеку препроцессора , которую вы можете использовать для генерации требуемых перегрузок без необходимости записывать все перегрузки вручную; но это довольно сложно.
Вот пример того, как сделать это с C ++ 98/03, предполагая, что функции, которые вы передаете в instruction
, не должны принимать аргументы по изменяемой ссылке, для этого вам также нужно иметь перегрузки для P1& p1
вместо просто const P1& p1
.
#include <iostream>
#include <boost/function.hpp>
#include <boost/bind.hpp>
template <typename Result = void>
class instruction
{
public:
template <typename Func>
instruction(Func func)
{
m_func = func;
}
template <typename Func, typename P1>
instruction(Func func, const P1& p1)
{
m_func = boost::bind(func, p1);
}
template <typename Func, typename P1, typename P2>
instruction(Func func, const P1& p1, const P2& p2)
{
m_func = boost::bind(func, p1, p2);
}
template <typename Func, typename P1, typename P2, typename P3>
instruction(Func func, const P1& p1, const P2& p2, const P3& p3)
{
m_func = boost::bind(func, p1, p2, p3);
}
Result execute()
{
return m_func();
}
private:
boost::function<Result ()> m_func;
};
double add(double a, double b)
{
return (a + b);
}
int main()
{
instruction<double> test(&add, 1.5, 2.0);
std::cout << "result: " << test.execute() << std::endl;
}
Пример: http://ideone.com/iyXp1