脚本回调参数和结果的自动编组

时间:2011-12-20 12:33:47

标签: c++ templates boost callback

我正在尝试自动生成函数,以便对基于变体的回调函数执行参数和结果编组。最终目标是简化回调与一种或多种脚本语言(可能是JavaScript和/或Lua)的集成。

我是C ++模板元编程(和SO)的新手,所以我确信我的方法中出现了一堆新手错误。这是我到目前为止所拥有的......

namespace mpl = boost::mpl;
namespace ft = boost::function_types;
namespace fusion = boost::fusion;

typedef boost::variant<boost::none_t, bool, int, double, std::wstring> Variant;
typedef std::vector<Variant> VariantList;

template < typename T >
VariantList AppendVariantToList(VariantList list, const T &t)
{
   list.push_back(t);
   return list;
}

template < typename T >
T get(Variant &v)
{
   return boost::get<T>(v);
}

typedef Variant callback_type(const VariantList &);

Variant InvokeCallback(const VariantList &args)
{
   // This method will eventually invoke the actual script callback.
   return true;
}

template < typename Function
   , class From = typename mpl::begin<ft::parameter_types<Function>>::type
   , class To   = typename mpl::end<ft::parameter_types<Function>>::type
   >
struct callback_binder
{
   typedef typename mpl::deref<From>::type arg_type;
   typedef typename mpl::next<From>::type next_iter_type;

   template < int n >
   static auto apply() -> decltype(boost::bind(AppendVariantToList<arg_type>, callback_binder<Function, next_iter_type, To>::apply<n + 1>(), boost::arg<n>()))
   {
      return boost::bind(AppendVariantToList<arg_type>, callback_binder<Function, next_iter_type, To>::apply<n + 1>(), boost::arg<n>());
   }

   static boost::function<Function> apply_1st(callback_type callback)
   {
      return boost::bind(get<bool>, boost::bind(callback, callback_binder<Function, From, To>::apply<1>()));
   }
};

template < typename Function, class To >
struct callback_binder < Function, To, To >
{
   template < int n >
   static auto apply() -> decltype(boost::bind(boost::value_factory<VariantList>()))
   {
      return boost::bind(boost::value_factory<VariantList>());
   }
};

template < typename Function >
boost::function<Function> make_callback(callback_type callback)
{
   return callback_binder<Function>::apply_1st(callback);
}

bool OnSomeEvent(int a, int b)
{
   const static auto callback(make_callback<BOOST_TYPEOF(OnSomeEvent)>(InvokeCallback));
   return callback(a, b);
}

InvokeCallback表示最终将调用脚本语言函数的函数。 OnSomeEvent是我想要调用脚本的回调函数的地方的一个例子。我们的想法是callback_binder::apply方法迭代OnSomeEvent的参数类型,并创建一个填充VariantList的函子,调用InvokeCallback并返回结果。

我似乎正在努力将< int n >模板参数引入apply方法以使我能够迭代boost::args。不幸的是,尝试编译上面的代码会导致MS VC ++ 2010 RTM崩溃,所以我不知道如何继续。

编辑:或许我要问的具体问题是,“如何在我正在使用的'metaloop'中访问boost::bind个占位符?”

感谢
西蒙

1 个答案:

答案 0 :(得分:0)

我认为我和你很像:我总是希望自动完成这类任务。

您可以使用模板自行滚动此自动编组。

但我更喜欢使用像SWIG,Simplified Wrapper和Interface Generator这样的东西。 http://www.swig.org/

不幸的是,上次我使用SWIG时它不支持我正在使用的所有C ++标准语言功能。但它通常足够好。

我也使用过OpenC ++。

我也使用了gccxml,http://www.gccxml.org,虽然它已经过时了。

请参阅Attribute & Reflection libraries for C++?

我没有使用过XRTTI。


最后,我有时会强迫自己使用一种我可以轻松预处理自己的宏语言,以便为必要的代码做好准备。

相关问题