给定两个explicit
构造函数重载(基于不同std::function<...>
类型),的返回值std::bind
可以选择其中一个(从而使调用变得模棱两可)
call of overloaded ‘Bar(std::_Bind_helper<false, void (Foo::*)(int),
Foo*, int>::type)’ is ambiguous
如果我将其中之一注释掉,则代码将编译!
我本以为使构造函数explicit
要么选择正确的重载,要么阻止两者都被选中?
当然,在我绑定的点显式创建一个std::function
是可行的:
Bar b(std::function<void(int)>(std::bind((&Foo::process), &f, 1)));
但是,我对为什么类型推断不起作用感到困惑?
std::bind
与两个构造函数签名均不匹配,explicit
则应避免同时选择这两个事实。std::bind
与两个构造函数签名之一匹配,则它们explicit
应该导致选择正确的事实。这里到底发生了什么?
完整的工作代码如下:
#include <functional>
struct Foo
{
void process(int) { }
};
struct Bar
{
// comment out either of these to compile
explicit Bar(std::function<void(int)>) {}
explicit Bar(std::function<void(short)>) {}
};
int main()
{
Foo f;
Bar b(std::bind(&Foo::process, &f, 1));
return 0;
}
使构造函数explicit
与必须完全匹配的参数无关!使构造函数显式的影响意味着不会Bar
使用该构造函数将其隐式转换为其他类型的对象。但是,如果尝试Bar
使用直接初始化(即Bar(x)
)来初始化对象,则将同时考虑这两个构造函数。
的结果std::bind()
肯定不是a std::function<Signature>
,即它与您的任何一个构造函数都不完全匹配。由于存在一个适用于函数对象的非explicit
构造std::function<Signature>
函数,因此两个签名都匹配:生成的绑定表达式不需要任何参数,但可以带参数,即,任何参数类型也不能用来区分两者中的哪一个的构造函数Bar
应该匹配。即使bind表达式需要一个参数,我也不认为它将比一个构造函数更喜欢一个构造函数。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句