我有以下代码,它可以工作:
template <typename ...Types>
struct Wrapper
{
template <void (*F)(typename Types::ParameterType...)>
static void toNativeFunction(Stuff stuff)
{
auto arguments = toConvertedArguments<Types...>(stuff);
std::apply(F, arguments);
}
};
其中
toConvertedArguments
有以下声明:
template<typename... Types>
using converted_tuple = std::tuple<typename Converter<Types>::ReturnType...>;
template<typename... Types>
converted_tuple<Types...> toConvertedArguments(Stuff stuff);
然后我这样称呼它:
void implementation(int);
template<typename T>
class SomeClass
{
using ParameterType = T;
}
//...
{
Wrapper<SomeClass<int>>::toNativeFunction<&implementation>(stuff);
}
这有效!但
Wrapper
存在的唯一原因是因为我无法在同一模板的模板函数定义中使用 Types...
。我的问题是我是否可以跳过 Wrapper
间接并拥有像这样“概念上”的东西:
template <typename ...Types, void (*F)(typename Types::ParameterType...)>
static void toNativeFunction(Stuff stuff);
这当然行不通,因为你不能有参数包后面的东西(或者更确切地说,这不是允许的例外之一)。我同样无法交换模板参数的顺序:
template <void (*F)(typename Types::ParameterType...), typename ...Types>
static void toNativeFunction(Stuff stuff);
从现在起它还不知道
Types
是什么。那么,我可以做一些奇特的事情来避免 Wrapper 类(也许使用内部 lambda 调用或其他东西吗?)。
您使用
auto
推迟拼写出函数签名
template<auto x>
using constant = std::integral_constant<decltype(x), x>;
template<auto F, typename ...Types>
static void toNativeFunction(std::integral_constant<void(*)(Types...), F>, Stuff stuff);
并称呼为
toNativeFunction(constant<implementation>{}, stuff);
可以是 API,也可以从原始函数转发。