c++ - 为什么这个重载的 std::function 参数不明确?
问题描述
我有下面的代码,其中一个类试图通过其构造函数获取两个 std::function 签名之一。我能够获得具有要编译的双参数的签名,但无参数签名无法编译,称调用不明确。
#include <functional>
class Foo
{
public:
void baz(double value) {
}
};
class Bar
{
public:
void baz() {
}
};
class Overloader {
public:
Overloader(std::function<void(double)> inFuncWithArg)
: funcWithArg(inFuncWithArg)
{
}
Overloader(std::function<void(void)> inFuncNoArg)
: funcNoArg(inFuncNoArg)
{
}
private:
std::function<void(double)> funcWithArg;
std::function<void(void)> funcNoArg;
};
int main()
{
Foo foo;
Bar bar;
// Compiles
Overloader overloader1(std::bind(static_cast<void(Foo::*)(double)>(&Foo::baz)
, &foo, std::placeholders::_1));
// Fails to compile - "call of overloaded ‘Overloader(std::_Bind_helper::type)’ is ambiguous"
Overloader overloader2(std::bind(static_cast<void(Bar::*)(void)>(&Bar::baz)
, &bar));
return 0;
}
我错过了什么导致失败?另外,有没有更简洁的方法来做到这一点?
这是完整的错误输出
main.cpp: In function ‘int main()’:
main.cpp:51:20: error: call of overloaded ‘Overloader(std::_Bind_helper::type)’ is ambiguous
, &bar));
^
main.cpp:32:5: note: candidate: Overloader::Overloader(std::function)
Overloader(std::function<void(void)> inFuncNoArg)
^~~~~~~~~~
main.cpp:27:5: note: candidate: Overloader::Overloader(std::function)
Overloader(std::function<void(double)> inFuncWithArg)
^~~~~~~~~~
解决方案
这个问题std::bind
比std::function
.
表达式的结果
std::bind(&Foo::baz, &foo, std::placeholders::_1)
可通过一个或多个参数调用,其中第一个参数可转换为双精度。
表达式的结果
std::bind(&Bar::baz, &bar)
可以用零个或多个参数调用,没有限制。
因此,第一个表达式只能初始化std::function<void(double)>
,但第二个表达式可以初始化std::function<void(double)>
或std::function<void(void)>
并且是不明确的。
真的,不要使用std::bind
. std::bind_front
有的话可以用。或者,使用 lambda。
std::bind_front
:
std::bind_front(&Foo::baz, &foo)
std::bind_front(&Bar::baz, &bar)
拉姆达:
[&foo](double) { foo.baz(value); }
[&bar] { bar.baz(); }
推荐阅读
- php - php结构与foreach成if
- django - 使用 Vue.js、Django Rest Framework 作为后端和 /api/ 在同一台服务器上配置 Nginx?
- javascript - Moment.js:错误->UnhandledPromiseRejectionWarning
- bash - 多行命令 BASH 和 python 切换选项
- c# - WindowsFormsHost 托管的 DataVizualization.Chart 中的 ContextMenu
- ruby-on-rails - Rails Turbo render_async:将 JWT 添加到异步请求
- rest - 我们可以为我们的服务配置双 @endpoint 吗?是这样吗,怎么配置呢?
- excel - 如何防止从受保护的excel表中复制
- c - 如何设置 RSS 以忽略具有 DPDK 20.11+ 的 I40E 端口的 TCP/UDP 的 L4 字段
- ios - 将 main.strings 文件中的现有字符串用于另一个元素的文本