无法从std::bind推导std::函数的模板参数
Could not deduce template argument for std::function from std::bind
我正试图找到一种方法来调用许多类成员函数,每个函数都有不同的参数,在调用前后都会发生某些已知的功能。
这个包装器函数是我尝试过的,但例如,对它的最后调用编译时没有出现错误:
'bool Wrapper(Work*,std::function<bool(Args…)>,Args&;…)':能够不推导的模板参数'std::函数<bool(double,std::string,Args…)>'from'std::_Bind<true,bool,std::_Pmf_wrap<bool(__thiscall工作::*)(double,std::string)、bool、Work、double、std::string>、Work*const>'
class Work
{
public:
void DoWork(int a, double b, string c);
private:
void Pre() {};
void Post() {};
bool Step1() { return true; }
bool Step2(int) { return true; }
bool Step3(double, string) { return true; }
};
template<typename... Args>
bool Wrapper(Work *work, std::function<bool(Args...)> func, Args&&... args)
{
work->Pre();
bool ret = func(std::forward<Args>(args)...);
work->Post();
return ret;
}
void Work::DoWork(int a, double b, string c)
{
if (!Wrapper<>(this, std::bind(&Work::Step1, this))) // error
return;
if (!Wrapper<int>(this, std::bind(&Work::Step2, this), a)) // error
return;
if (!Wrapper<double, string>(this, std::bind(&Work::Step3, this), b, c)) // error
return;
}
int main()
{
Work work;
work.DoWork(1, 2.0, "three");
return 0;
}
(乍一看,将前置和后置功能放在步骤中似乎更可取,但这是不可取的,因为上面是实际代码的一个非常简化的示例,并且步骤有多个返回位置,没有测试。)
我认为明确的模板参数将使模板解析成为可能。我做错了什么?
返回的std::bind
或lambda类型不是std::function
,从它们构造哪个std::function
将不明确。
一种解决方案是允许任何函子,而不使用std::function
template<typename F, typename... Args>
bool Wrapper(Work &work, F&& func, Args&&... args)
{
work.Pre();
const bool ret = std::forward<F>(func)(std::forward<Args>(args)...);
work.Post();
return ret;
}
演示
使用C++11,std::bind
可以被lambda替换,并且可以删除包装器的模板:
class Work
{
public:
void DoWork(int a, double b, string c);
private:
void Pre() {};
void Post() {};
bool Step1() { return true; }
bool Step2(int) { return true; }
bool Step3(double, string) { return true; }
friend bool Wrapper(Work *work, std::function<bool()> func);
};
bool Wrapper(Work *work, std::function<bool()> func)
{
work->Pre();
bool ret = func();
work->Post();
return ret;
}
void Work::DoWork(int a, double b, string c)
{
if (!Wrapper(this, [this]() -> bool { return this->Step1(); }))
return;
if (!Wrapper(this, [this, a]() -> bool { return this->Step2(a); }))
return;
if (!Wrapper(this, [this, b, c]() -> bool { return this->Step3(b, c); }))
return;
}
int main()
{
Work work;
work.DoWork(1, 2.0, "three");
return 0;
}
示例:http://coliru.stacked-crooked.com/a/2cd3b3e2a4abfcdc
相关文章:
- 带有指定长度字符* 参数的 std::regex_search 在 VS2017 中不起作用?
- 为什么 std::function 可以作为 std::not2 的参数?
- 传递给std::function template的template参数究竟代表什么
- 转换函数,将 std::数组的双精度作为参数或双精度作为参数单独转换
- 在C++中,使用带有 std::optional 参数的函数<T>来表示可选参数是否有意义?
- 将函数参数"const char*"转换为"std::string_view"是
- 当指向对象的指针作为参数传递给 std::thread 时,内存可见性
- 为什么 std::绑定错误参数可以成功?
- 使用模板化的键类型定义 std::map,该键类型基于作为参数接收的函数
- std::vector 没有重载函数的实例与参数列表匹配
- std::span<const T> 作为函数模板中的参数
- SegFault 同时使用 std::string::operator+= 和函数作为参数
- 如果模板没有可变参数,则 Lambda 被推导出为 std::function
- 将参数打包的参数传递到 std::queue 中,以便稍后使用不同的函数调用
- 在构造函数中使用可变参数初始化 std::tuple
- 为什么我不能将引用作为 std::async 的函数参数传递
- 转发变量参数列表以模拟 std::thread
- 使用 std::enable_if 限制派生类的模板参数时出现编译错误
- "std::shared_ptr":不是参数"_Ty"的有效模板类型参数
- 可变参数模板参数扩展 类型为 std::function 的类成员