gpt4 book ai didi

c++ - 用作模板参数,加上可变模板参数

转载 作者:可可西里 更新时间:2023-11-01 15:20:45 25 4
gpt4 key购买 nike

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

int lua_function( lua_State *L)

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

template <typename R, typename Arg1, typename Arg2, R F(Arg1, Args)>
struct wrapper

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

// This won't work
template <typename R, typename... Args, R F(Args...)>
struct wrapper

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

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;
}
};
};

这行得通,除了像这样包装一个函数

double sin(double d) {}

用户必须写

func_type<decltype(sin)>::func<sin>::apply

这很乏味。问题是:有没有更好、更用户友好的方法来做到这一点? (我不能使用函数模板来包装整个东西,因为函数参数不能用作模板参数。)

最佳答案

std::function 这样的东西和 std::result_of使用以下技术来执行有关可变参数模板的操作:

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 .可以说,如果您决定使用宏来删除重复项,这将是预处理器的合法使用。

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.

以上代码使用 gcc-4.5 在 ideone 编译.祝你好运地实现(可变地)弹出参数的应用程序(如果你对此提出问题,请给我留言)。您是否考虑过使用 Luabind?

关于c++ - 用作模板参数,加上可变模板参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6016811/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com