我定义了两个重载模板函数。他们两个都以函数指针作为参数。区别在于,第一个函数是类的成员,而第二个函数不是。
当我尝试传递非成员函数类的模板函数时,编译器会选择该函数为类成员的模板函数。
结果生成了编译器错误。
下面是代码
#include <type_traits>
#include <iostream>
#include <deque>
#include <thread>
#include <functional>
class Worker
{
public:
Worker()
{
}
template<typename _Callable, typename Object, typename... _Args>
void QueueFunction(_Callable __f, Object obj, _Args... __args)
{
funcs.emplace_back([=]()mutable
{
(obj.*__f)(__args...);
});
std::cout << "size::" <<funcs.size()<<std::endl;
std::cout << funcs.empty()<<std::endl;
}
template<typename _Callable, typename... _Args>
void QueueFunction(_Callable __f, _Args... __args)
{
funcs.emplace_back([=]()mutable
{
(*__f)(__args...);
});
}
std::deque<std::function<void()>> funcs;
};
void sub(int x ,int y)
{
std::cout << "sub::result: " << x-y << std::endl;
}
int main()
{
Worker w;
w.QueueFunction(&sub,5,6);
}
我希望可以选择以下功能
template<typename _Callable, typename... _Args>
void QueueFunction(_Callable __f, _Args... __args)
答案 0 :(得分:3)
SFINAE不查看函数的主体,仅考虑其声明。
这意味着当我们谈论重载解决方案时,您的类如下所示:
class Worker
{
template<typename A, typename B, typename... Cs>
void QueueFunction(A a, B b, Cs... cs)
{}
template<typename A, typename Bs>
void QueueFunction(A a, Bs... bs)
{}
};
考虑到这一点,将w.QueueFunction(&sub,5,6);
与第一个绑定更牢固是很有意义的。
编辑:您所做的基本上是在重新发明std::bind
,所以您最好使用它。它将同时平滑处理函子,成员函数以及所有其他内容。
template<typename... Args>
void QueueFunction(Args&&... args) {
funcs.emplace_back(std::bind(std::forward<Args>(args)...));
}