gpt4 book ai didi

c++ - 为什么在模板推导过程中没有选择正确的功能

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:58:54 25 4
gpt4 key购买 nike

我定义了两个重载模板函数。它们都以函数指针作为参数。不同之处在于,在第一个中,函数是类的成员,而在第二个中则不是。
当我尝试传入非成员函数类的模板函数时,编译器会选择该函数是类成员的模板函数。结果产生了编译器错误。

下面是代码

#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)

最佳答案

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); 与第一个函数的绑定(bind)更牢固。

编辑:您所做的基本上是重新发明 std::bind,因此您不妨改用它。它将同时顺利处理仿函数、成员函数和其他一切。

template<typename... Args>
void QueueFunction(Args&&... args) {
funcs.emplace_back(std::bind(std::forward<Args>(args)...));
}

关于c++ - 为什么在模板推导过程中没有选择正确的功能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56099801/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com