闭包 class 的可变参数模板 deduction/matching
Variadic template deduction/matching for a closure class
我正在尝试创建一种闭包回调 class 和 运行 解决模板参数推导和匹配的一些问题
( class 的工作原理如下:在构造时,它将把一个成员函数或非成员函数以及一个变量 (CAPARGS
) 数量的参数放入一个闭包中。闭包然后可以使用可变数量的参数 (CALLARGS
) 调用,它将使用 CAPARGS
和 CALLARGS
调用其回调函数。)
- 我在调用它的构造函数时遇到编译错误(见下文
"Test code",标出两个错误)。
- 这两种情况都会出现编译错误,因为它找不到匹配的构造函数。
- 我在 "Class code" 下标记了在每个错误中应该采用的构造函数,并且我在下面给出了为该构造函数给出的错误(不匹配的原因)。
错误 1:
candidate template ignored: could not match 'function' against 'void (*)(int)'
错误 2:
note: candidate template ignored: failed template argument deduction
Class代码:
template <class... CALLARGS>
class Closure{
public:
// Constructor intended for use at ERROR 1
template <class OBJ, class... CAPARGS>
Closure(OBJ* obj, void (OBJ::*fct)(CAPARGS..., CALLARGS...), CAPARGS... capArgs){
callback =
[=] (CALLARGS... callArgs) -> void{
(obj->*fct)(capArgs..., callArgs...);
};
}
// Constructor intended for use at ERROR 1
template <class... CAPARGS>
Closure(std::function<void(CAPARGS..., CALLARGS...)>, CAPARGS... capArgs){
callback =
[=] (CALLARGS... callArgs) -> void{
fct(capArgs..., callArgs...);
};
}
void operator () (CALLARGS... callArgs){
callback(callArgs...);
}
private:
std::function<void(CALLARGS...)> callback;
};
测试代码:
class A{
public:
virtual void fct(int a){
...
}
};
void plusF(int a){
...
}
int main(void) {
A a;
Closure<int> callF(plusF); // **ERROR 1 from here**
Closure<int> callA(&a, &A::fct); // **ERROR 2 from here**
callF(1);
callA(2);
}
我知道我可能正在做超出我能力范围的事情。但我能以某种方式解决这个问题吗?
(顺便说一句,附带问题:将此 class 称为闭包是否合理,或者这样的结构是否有不同的名称?)
您的某些可变参数模板不可扣除(或产生冲突),您可以改为:
template <class... CALLARGS>
class Closure{
public:
template <class OBJ, typename M, class... CAPARGS>
Closure(OBJ* obj, M (OBJ::*fct), CAPARGS... capArgs){
callback =
[=] (CALLARGS... callArgs) -> void{
(obj->*fct)(capArgs..., callArgs...);
};
}
template <typename F, class... CAPARGS>
Closure(F fct, CAPARGS... capArgs){
callback =
[=] (CALLARGS... callArgs) -> void{
fct(capArgs..., callArgs...);
};
}
void operator () (CALLARGS... callArgs){
callback(callArgs...);
}
private:
std::function<void(CALLARGS...)> callback;
};
std::bind
可能是一个更简单的选择:
using namespace std::placeholders;
A a;
auto callF = std::bind(plusF, _1);
auto callA = std::bind(&A::fct, &a, _1);
callF(1);
callA(2);
我正在尝试创建一种闭包回调 class 和 运行 解决模板参数推导和匹配的一些问题
( class 的工作原理如下:在构造时,它将把一个成员函数或非成员函数以及一个变量 (CAPARGS
) 数量的参数放入一个闭包中。闭包然后可以使用可变数量的参数 (CALLARGS
) 调用,它将使用 CAPARGS
和 CALLARGS
调用其回调函数。)
- 我在调用它的构造函数时遇到编译错误(见下文 "Test code",标出两个错误)。
- 这两种情况都会出现编译错误,因为它找不到匹配的构造函数。
- 我在 "Class code" 下标记了在每个错误中应该采用的构造函数,并且我在下面给出了为该构造函数给出的错误(不匹配的原因)。
错误 1:
candidate template ignored: could not match 'function' against 'void (*)(int)'
错误 2:
note: candidate template ignored: failed template argument deduction
Class代码:
template <class... CALLARGS>
class Closure{
public:
// Constructor intended for use at ERROR 1
template <class OBJ, class... CAPARGS>
Closure(OBJ* obj, void (OBJ::*fct)(CAPARGS..., CALLARGS...), CAPARGS... capArgs){
callback =
[=] (CALLARGS... callArgs) -> void{
(obj->*fct)(capArgs..., callArgs...);
};
}
// Constructor intended for use at ERROR 1
template <class... CAPARGS>
Closure(std::function<void(CAPARGS..., CALLARGS...)>, CAPARGS... capArgs){
callback =
[=] (CALLARGS... callArgs) -> void{
fct(capArgs..., callArgs...);
};
}
void operator () (CALLARGS... callArgs){
callback(callArgs...);
}
private:
std::function<void(CALLARGS...)> callback;
};
测试代码:
class A{
public:
virtual void fct(int a){
...
}
};
void plusF(int a){
...
}
int main(void) {
A a;
Closure<int> callF(plusF); // **ERROR 1 from here**
Closure<int> callA(&a, &A::fct); // **ERROR 2 from here**
callF(1);
callA(2);
}
我知道我可能正在做超出我能力范围的事情。但我能以某种方式解决这个问题吗?
(顺便说一句,附带问题:将此 class 称为闭包是否合理,或者这样的结构是否有不同的名称?)
您的某些可变参数模板不可扣除(或产生冲突),您可以改为:
template <class... CALLARGS>
class Closure{
public:
template <class OBJ, typename M, class... CAPARGS>
Closure(OBJ* obj, M (OBJ::*fct), CAPARGS... capArgs){
callback =
[=] (CALLARGS... callArgs) -> void{
(obj->*fct)(capArgs..., callArgs...);
};
}
template <typename F, class... CAPARGS>
Closure(F fct, CAPARGS... capArgs){
callback =
[=] (CALLARGS... callArgs) -> void{
fct(capArgs..., callArgs...);
};
}
void operator () (CALLARGS... callArgs){
callback(callArgs...);
}
private:
std::function<void(CALLARGS...)> callback;
};
std::bind
可能是一个更简单的选择:
using namespace std::placeholders;
A a;
auto callF = std::bind(plusF, _1);
auto callA = std::bind(&A::fct, &a, _1);
callF(1);
callA(2);