我想声明一个方法-variadic,其中它的签名来自于一个"旧式";函数签名作为模板参数。
例如,您可以使用函数签名(例如(声明std::function
std::function<int(float,float)> f;
现在我想要一个模板,它接受这样的函数签名,并以某种方式声明一个方法:
template <typename F>
struct Foo {
[F's-return-type] Method(F's-Arg-pack]...) { ... }
};
因此,如果你按照如下方式实例化它,你会得到一个如下的方法:
Foo<int(float,float)> foo;
int x = foo.Method(1.0f, 2.0f);
或者可能有另一种方法可以做到这一点?
您可以使用一个非常简单的部分专用化来反汇编F
:
template <class F>
struct Foo;
template <class Ret, class... Params>
struct Foo<Ret(Params...)> {
Ret Method(Params...) { /* ... */ }
};
在Coliru 上实时观看
当然!结果类型很简单,这就是简单的std::function::result_type
。提取参数类型不那么简单,并且需要部分类专门化(至少在我的解决方案中(:
template<class F> struct Foo;
template<class R, class... Args>
struct Foo<std::function<R(Args...)>
{
R Method(Args... args) { ... }
};
您需要部分专业化,每种函数都需要一个。希望对于正则函数(所以不是讨厌的函数(,有更少的:
template <class Sig>
struct Foo;
template <typename Ret, typename... Ts>
struct Foo<Ret(Ts...)> {
Ret Method(Ts...) const { /* .. */ }
};
// C-ellipsis (printf-like)
template <typename Ret, typename... Ts>
struct Foo<Ret(Ts..., ...)> {
Ret Method(Ts..., ...) const { /* .. va_arg and co */ }
};
对于方法,组合较大(cv限定符(x4(,ref限定符(x3(,因此为24(。