我正在尝试创建一个类,它将使用可变数量的参数存储指向函数的指针,并在以后调用它。
我们的想法是为函数创建一个包装器,在对象析构时调用所述函数。这样我就可以确保在退出某个函数后进行一些清理。
我现在拥有的是Faheem Mitha在here发布的一些修改后的代码。
以下是带有示例的工作代码(我正在使用Visual Studio 2015进行编译):
#include "stdafx.h"
#include <tuple>
#include <iostream>
using namespace std;
template<int...> struct seq {};
template<int N, int... S> struct gens : gens<N - 1, N - 1, S...> {};
template<int... S> struct gens<0, S...> { typedef seq<S...> type; };
template<typename Return, typename... Args> class CallOnExit
{
Return(*_func)(Args...);
std::tuple<Args...> _args;
template<int... S> Return call_func(seq<S...>)
{
return _func(std::get<S>(_args)...);
}
Return call()
{
return call_func(typename gens<sizeof...(Args)>::type());
}
public:
CallOnExit(Return(*func)(Args...), Args&&... args)
{
_func = func;
_args = std::forward_as_tuple(args...);
}
~CallOnExit()
{
if (_func != nullptr)
call();
}
};
void f(int i, double d)
{
cout << i << endl << d << endl;
}
int main()
{
{
CallOnExit<void, int, double> c(f, 1, 2);
}
cin.get();
return 0;
}
问题是我必须在Arduino平台上进行这项工作,其中stl不可用(所以没有std :: tuple,没有std :: forward,没有std :: get)。 Arduino支持C ++ 11。
使这个示例在没有stl的情况下工作所需的最少工作量是什么?
答案 0 :(得分:2)
我们的想法是为函数创建一个包装器,在对象析构时调用所述函数。这样我就可以确保在退出某个函数后进行一些清理。
您尝试使用的代码似乎有点过于思考,或者至少是针对某些其他特定用途而定制的。对于上面的引用,这里是我将如何使用lambdas和简单函数完成任务。
现在,调用可以根据需要自定义,并且实现保持简单:
class Battery_Update_Handler(web.RequestHandler):
def post(self):
self.application.battery0.status = dict(
can_id=self.get_argument("can_id", None),
can_dlc=self.get_argument("can_dlc", None),
data=self.get_argument("data", None))
class Application(web.Application):
def __init__(self):
self.battery0 = Battery('bat0')
routing = [
(r'/api/battery/(data|)', API_Handler),
(r'/update-battery', Battery_Update_Handler)
]
settings = {
'template_path': os.path.join(os.path.dirname(__file__), "templates"),
'static_path': os.path.join(os.path.dirname(__file__), "static"),
}
web.Application.__init__(self, routing, debug=True, **settings)
答案 1 :(得分:0)
希望这有帮助
#include <tuple>
#include <iostream>
using namespace std;
template<int...> struct seq {};
template<int N, int... S> struct gens : gens<N - 1, N - 1, S...> {};
template<int... S> struct gens<0, S...> { typedef seq<S...> type; };
// NEW
template <int N, typename ... Args>
struct typeCont;
template <typename A0, typename ... Args>
struct typeCont<0, A0, Args...>
{ using type = A0; };
template <int N, typename A0, typename ... Args>
struct typeCont<N, A0, Args...>
{ using type = typename typeCont<N-1, Args...>::type; };
// NEW
template <typename X, typename ... Args>
class packCont;
template <typename X, typename A0, typename ... Args>
class packCont<X, A0, Args...>
{
public:
X x;
packCont<A0, Args...> n;
public:
packCont (X const & x0, A0 const & a0, Args const & ... args)
: x(x0), n(a0, args...)
{ }
X const & getX () const
{ return x; }
packCont<A0, Args...> const & getN () const
{ return n; }
};
template <typename X>
class packCont<X>
{
private:
X x;
public:
packCont (X const & x0)
: x(x0)
{ }
X const & getX () const
{ return x; }
};
// NEW
template <int N>
struct getPc
{
template <typename ... Args>
static typename typeCont<N, Args...>::type const &
func (packCont<Args...> const & pc)
{ return getPc<N-1>::func(pc.getN()); }
};
template <>
struct getPc<0>
{
template <typename A0, typename ... Args>
static A0 const & func (packCont<A0, Args...> const & pc)
{ return pc.getX(); }
};
template<typename Return, typename... Args> class CallOnExit
{
Return(*_func)(Args...);
packCont<Args...> _args; // MODIFIED
// MODIFIED
template<int... S> Return call_func(seq<S...>)
{
return _func( getPc<S>:: template func<Args...>(this->_args) ... );
}
Return call()
{
return call_func(typename gens<sizeof...(Args)>::type());
}
public:
// MODIFIED
CallOnExit(Return(*func)(Args...), Args&&... args)
: _func(func), _args(args...)
{ }
~CallOnExit()
{
if (_func != nullptr)
call();
}
};
void f(int i, double d)
{
cout << i << endl << d << endl;
}
int main()
{
{
CallOnExit<void, int, double> c(f, 1, 2);
}
cin.get();
return 0;
}