如何从函数指针推导参数列表? [英] How to Deduce Argument List from Function Pointer?
问题描述
给定两个或更多示例函数,是否可以编写模板代码以推断出作为模板参数提供的函数的自变量?
Given two or more example functions, is it possible to write templated code which would be able to deduce the arguments of a function provided as a template parameter?
这是很有启发性的例子:
This is the motivating example:
void do_something(int value, double amount) {
std::cout << (value * amount) << std::endl;
}
void do_something_else(std::string const& first, double & second, int third) {
for(char c : first)
if(third / c == 0)
second += 13.7;
}
template<void(*Func)(/*???*/)>
struct wrapper {
using Args = /*???*/;
void operator()(Args&& ... args) const {
Func(std::forward<Args>(args)...);
}
};
int main() {
wrapper<do_something> obj; //Should be able to deduce Args to be [int, double]
obj(5, 17.4); //Would call do_something(5, 17.4);
wrapper<do_something_else> obj2; //Should be able to deduce Args to be [std::string const&, double&, int]
double value = 5;
obj2("Hello there!", value, 70); //Would call do_something_else("Hello there!", value, 70);
}
在/* ??? */
的两种用法中,我都在尝试找出可以放置这种代码的地方.
In both uses of /*???*/
, I am trying to work out what I could put there that would enable this kind of code.
以下内容似乎无效,这是因为 Args
在首次使用之前未定义(此外,我不得不假设还有许多语法错误),即使这样做,我仍在寻找不需要显式编写类型的版本:
The following doesn't appear to work, due to Args
not being defined before its first use (along with what I have to assume are numerous syntax errors besides), and even if it did, I'm still looking for a version that doesn't require explicit writing of the types themselves:
template<void(*Func)(Args ...), typename ... Args)
struct wrapper {
void operator()(Args ...args) const {
Func(std::forward<Args>(args)...);
}
};
wrapper<do_something, int, double> obj;
推荐答案
使用C ++ 17,我们可以使用自动模板非类型参数,从而使 Wrapper< do_something>w {}
语法 1).
With C++17 we can have auto template non-type parameters which make possible the Wrapper<do_something> w{}
syntax 1).
要推断出 Args ...
,您可以使用专业化来做到这一点./p>
As for deducing Args...
you can do that with a specialization.
template <auto* F>
struct Wrapper {};
template <class Ret, class... Args, auto (*F)(Args...) -> Ret>
struct Wrapper<F>
{
auto operator()(Args... args) const
{
return F(args...);
}
};
Wrapper<do_something> w{};
w(10, 11.11);
1)如果没有C ++ 17,就不可能有 Wrapper< do_something>w {}
不错的语法.
1) Without C++17 it's impossible to have the Wrapper<do_something> w{}
nice syntax.
您能做的最好的事情是:
The best you can do is:
template <class F, F* func>
struct Wrapper {};
template <class Ret, class... Args, auto (*F)(Args...) -> Ret>
struct Wrapper<Ret (Args...), F>
{
auto operator()(Args... args) const
{
return F(args...);
}
};
Wrapper<declype(do_something), do_something> w{};
这篇关于如何从函数指针推导参数列表?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!