在另一个函数调用中包装模板化函数调用

wrapping templated function call in another function call

任何人都知道是否可以做类似以下的事情:

void my_inner_func(int i, double d, ...) { 
    // do stuff here
}

template <typename Func, typename... Args>
void my_outer_func(Func&& f,Args&&... args){
    // do other stuff here, put this inside loop, etc
    f(std::forward<Args>(args)...);
}

template <typename OuterFunc,typename InnerFunc,typename... Args>
void func(OuterFunc&& outer, InnerFunc&& inner, Args&&...args) {
    outer(std::forward<InnerFunc>(inner),std::forward<Args>(args)...);
}

调用代码可能如下所示:

func(my_outer_func, my_inner_func, 1, 2.0, ...);

我 运行 遇到的问题是无法推断出 OuterFunction 的类型。我尝试了很多不同的方法,包括将 func 转换为仿函数以及将 OuterFunc 设为模板模板参数。

如果您将 my_outer_func 设为函数对象而不是函数,它会起作用:

struct my_outer_func {
    template <typename Func, typename... Args>
    void operator()(Func&& f,Args&&... args) const {
        // do other stuff here, put this inside loop, etc
        f(std::forward<Args>(args)...);
    }
};

然后:

func(my_outer_func(), my_inner_func, 1, 2.0);

如果您不喜欢调用处的括号,则可以在创建全局结构实例时将其删除:

struct {
    template <typename Func, typename... Args>
    void operator()(Func&& f,Args&&... args) const {
        // do other stuff here, put this inside loop, etc
        f(std::forward<Args>(args)...);
    }
} my_outer_func;

my_outer_func 传递给 func 时需要用 lambda 包裹起来:

func([](auto &&... params){my_outer_func(decltype(params)(params)...);}, my_inner_func, 1, 2.0);

其中 decltype(params)(params) 等同于 std::forward<decltype(params)>(params),但输入更少。

或者,my_outer_func 本身可以是一个 lambda:

auto my_outer_func = []<typename Func, typename... Args>(Func&& f,Args&&... args)
{
    f(std::forward<Args>(args)...);
};

lambda 中的显式模板参数是 C++20 的一项功能。 Pre-C++20 你必须使用 auto,就像第一个例子一样。