我正在尝试编写一个相当简单的类,它接受一个函数,一些参数,并且可以在以后用参数执行该函数。
目前,这是我的代码:
template<typename R, typename... Args>
class Delayed
{
public:
using FunctionT = std::function<R(Args...)>;
Delayed(FunctionT func, Args... args) : func(func), args(std::forward<Args>(args)...)
{
}
private:
FunctionT func;
std::tuple<Args...> args;
};
int main()
{
std::function<double(double)> doubleMe = [](double x) { return x * 2.0; };
//Works
Delayed<double, double> delayed1(doubleMe, 2.0);
//Doesn't work
Delayed<double(double)> delayed2(doubleMe, 2.0);
}
问题在于,当我将double(double)
作为参数传递而不是R
double
而Args
为double
时,它会通过{{1} } {}} double(double)
,R
。
According to cppreference,Args
的模板参数为std::function
。因此,如果我给它template< class R, class... Args >
,它将为参数A(B,C)
传递A
并为变量参数R
传递B,C
。但是当我将它传递给我的班级时,它会Args
传递给A(B,C)
,并且不会为可变参数R
传递任何内容。
该函数语法应该如何使用?为什么它适用于Args
而不是我的班级?
答案 0 :(得分:2)
因此,如果我给它
A(B,C)
,它将为参数A
传递R
,为变量参数B,C
传递Args
。
是的,但不是出于您的想法。仔细观察,您会发现std::function
部分专门针对任何函数类型:
template<typename R, typename... Args>
class function<R(Args...)>;
// ^^^^^^^^^^^^
你可以把它想象成非常原始的模式匹配。如果您使用function
实例化int(int, double)
,那么R
为int
,而Args
为int, double
则有意义。如果(部分)特化是比catch-all泛型主模板更好的匹配,则选择它,这就是这里发生的事情。
请记住:double(double)
是一种类型,它是一种功能。没有涉及它的任何特殊规则。所以,在你的情况下,你会这样做:
template<typename R, typename... Args>
class Delayed<R(Args...)> : public Delayed<R, Args...> {
// ^^^^^^^^^^^^
// partially specialize to decompose function types
// We need to inherit constructors (only).
using Delayed<R, Args...>::Delayed;
};
希望它能解决困惑。