首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >函数作为模板参数,加上可变模板参数

函数作为模板参数,加上可变模板参数
EN

Stack Overflow用户
提问于 2011-05-16 19:38:43
回答 2查看 5K关注 0票数 11

我正在编写一个通用的函数包装器,它可以将任何函数包装到lua风格的调用中,其形式为

int lua_function( lua_State *L)

我希望包装器函数是动态生成的,所以我正在考虑将该函数作为模板参数传递。如果您知道参数的数量(例如,2),这是微不足道的:

代码语言:javascript
复制
template <typename R, typename Arg1, typename Arg2, R F(Arg1, Args)>
struct wrapper

但是,我不知道这个数字,所以我请求可变模板参数来帮助我

代码语言:javascript
复制
// This won't work
template <typename R, typename... Args, R F(Args...)>
struct wrapper

上面的代码不能编译,因为可变参数必须是最后一个。所以我使用了两级模板,外层模板捕获类型,内层模板捕获函数:

代码语言:javascript
复制
template <typename R, typename... Args>
struct func_type<R(Args...)>
{
  // Inner function wrapper take the function pointer as a template argument
  template <R F(Args...)>
  struct func
  {
    static int call( lua_State *L )
    {
      // extract arguments from L
      F(/*arguments*/);
      return 1;
    }
  };
};

这是可行的,除了包装像这样的函数

代码语言:javascript
复制
double sin(double d) {}

用户必须写下

代码语言:javascript
复制
func_type<decltype(sin)>::func<sin>::apply

这太乏味了。问题是:有没有更好、更用户友好的方法呢?(我不能使用函数模板来包装整个内容,因为函数参数不能用作模板参数。)

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-05-16 21:05:56

std::functionstd::result_of这样的东西使用以下技术来对可变模板执行所需的操作:

代码语言:javascript
复制
template<typename Signature>
struct wrapper; // no base template

template<typename Ret, typename... Args>
struct wrapper<Ret(Args...)> {
    // instantiated for any function type
};

您可以扩展上面的代码来添加一个非类型的Ret(&P)(Args...)模板参数(指向函数的指针也可以),但是您仍然需要一个用户级别的decltype,即wrapper<decltype(sin), sin>::apply。可以说,如果您决定使用宏来消除重复,那么这将是对预处理器的合法使用。

代码语言:javascript
复制
template<typename Sig, Sig& S>
struct wrapper;

template<typename Ret, typename... Args, Ret(&P)(Args...)>
struct wrapper<Ret(Args...), P> {
    int
    static apply(lua_State*)
    {
        // pop arguments
        // Ret result = P(args...);
        // push result & return
        return 1;
    }
};

// &wrapper<decltype(sin), sin>::apply is your Lua-style wrapper function.

上面的内容是在ideone用gcc-4.5语言编译的。祝你实现apply (可变地)弹出参数(如果你对此有疑问的话,请给我留言)。你有没有考虑过使用Luabind?

票数 9
EN

Stack Overflow用户

发布于 2011-05-16 20:03:55

正如@Juraj在他的评论中所说的,函数指针可以是一个模板参数,参见下面的简单示例:

代码语言:javascript
复制
#include <iostream>
#include <boost/typeof/typeof.hpp>

void f(int b, double c, std::string const& g)
{
  std::cout << "f(): " << g << std::endl;
}

template <typename F, F* addr>
struct wrapper
{
  void operator()()
  {
    std::string bar("bar");
    (*addr)(1, 10., bar);
  }  
};

int main(void)
{
  wrapper<BOOST_TYPEOF(f), &f> w;
  w();
  return 0;
}

工作版本:http://www.ideone.com/LP0TO

我像往常一样使用BOOST_TYPEOF,我总是在当前标准中提供示例,但它做的事情与decltype类似。这就是你要找的东西吗?

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6016811

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档