函数式模板语法
Function-style template syntax
我正在尝试编写一个相当简单的 class,它接受一个函数和一些参数,并且可以在稍后使用参数执行该函数。
目前,这是我的代码:
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
,而是传递 double(double)
到 R
而 Args
.
什么都没有
According to cppreference,std::function
的模板参数是 template< class R, class... Args >
。因此,如果我给它 A(B,C)
,它将为参数 R
传递 A
,为可变参数 Args
传递 B,C
。但是,当我将其传递给我的 class 时,它会为 R
传递 A(B,C)
,而不会为可变参数 Args
.
传递任何内容
这个函数语法应该如何使用,为什么它适用于 std::function
而不是我的 class?
So if I give it A(B,C)
, it will pass A
for the argument R
and B,C
for the variadic argument Args
.
是的,但不是你想的那样。如果仔细观察,您会发现 std::function
部分特化了任何函数类型:
template<typename R, typename... Args>
class function<R(Args...)>;
// ^^^^^^^^^^^^
你可以把它想象成非常原始的模式匹配。如果用int(int, double)
实例化function
,那么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;
};
希望它能消除困惑。
我正在尝试编写一个相当简单的 class,它接受一个函数和一些参数,并且可以在稍后使用参数执行该函数。
目前,这是我的代码:
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
,而是传递 double(double)
到 R
而 Args
.
According to cppreference,std::function
的模板参数是 template< class R, class... Args >
。因此,如果我给它 A(B,C)
,它将为参数 R
传递 A
,为可变参数 Args
传递 B,C
。但是,当我将其传递给我的 class 时,它会为 R
传递 A(B,C)
,而不会为可变参数 Args
.
这个函数语法应该如何使用,为什么它适用于 std::function
而不是我的 class?
So if I give it
A(B,C)
, it will passA
for the argumentR
andB,C
for the variadic argumentArgs
.
是的,但不是你想的那样。如果仔细观察,您会发现 std::function
部分特化了任何函数类型:
template<typename R, typename... Args>
class function<R(Args...)>;
// ^^^^^^^^^^^^
你可以把它想象成非常原始的模式匹配。如果用int(int, double)
实例化function
,那么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;
};
希望它能消除困惑。