是否可以在没有显式专用化的情况下调用可变参数模板函数?

Is it possible to invoke a variadic template function without explicit specialization?

本文关键字:变参 调用 情况下 参数 函数 专用 是否      更新时间:2023-10-16

我试图编写一个函数来转发可变参数模板函数的参数,类似于std::invoke。这是代码:

#include <functional>
template<class... Args>
void f(Args&&... args) { }
template<template<class...> class F, class... Args>
void invoke(F<Args...> f, Args&&... args) {
f(std::forward<decltype(args)>(args)...);
}
int main() {
invoke(f, 1, 2, 3);
std::invoke(f, 1, 2, 3);
}

但是,我的invokestd::invoke都无法编译。 G++抱怨它无法推断出模板参数template<class ...> class F。那么,是否可以在没有显式模板专用化的情况下调用可变参数模板函数呢?

请注意,函数模板表示一系列函数。例如,当您将其传递给函数时,它需要解析为模板的某种专用化。我理解您要尝试使用自定义invoke的参数做什么(将函数模板捕获为模板(,但遗憾的是,这仅适用于类模板,而不适用于函数模板。

您需要另一个级别的间接寻址。即,传递一个函子或 lambda 将参数转发给f

invoke([](auto&&... xs) { f(decltype(xs)(xs)...); }, 1, 2, 3);

不同之处在于,现在参数是一个类非模板,因此可以通过您的invoke推导出来。

随着此更改,您更改函数以完全推导第一个参数的额外要求:

template<class F, class... Args>
void invoke(F&& f, Args&&... args) {
f(forward<Args>(args)...);
}

如果函数包装在模板类中,那么您应该能够将此模板类作为模板模板参数传递:

#include <functional>
template<class... Args> struct Wrap
{
static void f(Args&&... args) { }
};
template<template<class...> class F, class... Args>
void invoke(Args&&... args) {
Wrap<Args...>::f(std::forward<Args>(args)...);
}
int main() {
invoke<Wrap>(1, 2, 3);
}

在线编译器