【问题标题】:Can I get a parameter pack from an (old-style) function signature?我可以从(旧式)函数签名中获取参数包吗?
【发布时间】:2021-03-18 20:17:42
【问题描述】:

我想声明一个方法 - 可变参数 - 它的签名来自“旧式”函数签名作为模板参数。

例如,您可以使用函数签名声明 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);

或者也许有其他方法可以做到这一点?

【问题讨论】:

标签: c++ c++17 variadic-templates variadic-functions


【解决方案1】:

您可以使用非常简单的部分特化来反汇编F

template <class F>
struct Foo;

template <class Ret, class... Params>
struct Foo<Ret(Params...)> {
    Ret Method(Params...) { /* ... */ }
};

See it live on Coliru

【讨论】:

  • 我什至没有想到以这种方式部分专业化。部分专业化非常灵活! (稍后会选择一个绿色检查的答案......)
【解决方案2】:

当然!结果类型很简单,就是std::function::result_type。提取参数类型不太直接,并且需要部分类专业化(至少在我的解决方案中):

template<class F> struct Foo;
template<class R, class... Args>
struct Foo<std::function<R(Args...)>
{
   R Method(Args... args) { ... }
};

【讨论】:

  • 我什至没有想到以这种方式部分专业化。部分专业化非常灵活! (稍后会选择一个绿色检查的答案......)
【解决方案3】:

您需要部分专业化,一种用于每种功能。 希望对于常规功能(所以不是abominable functions),更少:

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-qualifier (x4), ref-qualifier (x3), so 24)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-31
    • 2023-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-18
    相关资源
    最近更新 更多