使模板函数反映其模板参数的签名

Making a template function mirror its template argument's signature

我有一个模板函数:

template <??? func>
??? wrapper(??? args) {
    // ... Stuff
    return func(args);
}

它应该与 func 非类型模板参数具有相同的签名。

我得到的最接近的是在模板声明中使用 auto 然后使用某种形式的函数特征来推断 return 类型,但是,这种方法不允许推断整体参数。

理想情况下,

template <typename R, typename... Args, R(*func)(Args...)>
R wrapper(Args&&... args); // ...

或其他一些虚构的语法将 A. 被允许并且 B. 从 func.

推导出 RArgs

func 必须在编译时指定并且函数可以没有任何附加参数(我需要取包装器的地址)。

此时我觉得我现在的解决方案,

template <auto func, typename... Args>
auto wrapper(Args&&... args) {
    return func(std::forward<Args>(args)...);
}

无法改进,因为似乎不可能生成“纯”可变参数模板参数(在将它们“存储”到任何地方(例如 tuple)后取回它们)。这很可悲,因为它强制手动提供 Args 。但我当然希望看到有人证明我在这方面是错误的!

您可以创建特征来提取返回类型和参数。问题是仅从函数声明中处理元数。

如果你能用class/functor包裹起来,那就有可能:

template <auto func> struct wrapper_t;

template <typename Ret, typename ... Ts, Ret (*func)(Ts...)>
struct wrapper_t<func>
{
    Ret operator() (Ts... args) const { return func(std::forward<Ts>(args)...); }
};

// handle ellipsis functions ala printf
template <typename Ret, typename ... Ts, Ret (*func)(Ts..., ...)>
struct wrapper_t<func>
{
    template <typename ...EllipsisArgs>
    Ret operator() (Ts... args, EllipsisArgs&&... ellipisisArgs) const {
        return func(std::forward<Ts>(args)...,
                    std::forward<EllipsisArgs>(ellipisisArgs)...);
    }
};

template <auto func>
constexpr wrapper_t<func> wrapper{};

Demo