返回类型 std::bind 隐式转换为两个不同的显式构造函数
return type of std::bind implicitly convertible to two different explicit constructors
给定两个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(x)
)初始化 Bar
对象,则将考虑这两个构造函数。
std::bind()
的结果肯定不是std::function<Signature>
,即它不完全匹配你的任何一个构造函数。由于std::function<Signature>
有一个适用于函数对象的非explicit
构造函数,因此两个签名确实匹配:生成的绑定表达式不需要任何参数,但它可以接受参数,即任何参数类型也不能用于区分Bar
的两个构造函数中的哪一个应该匹配。即使绑定表达式需要一个参数,我认为它也不会用于偏爱一个构造函数而不是另一个构造函数。
相关文章:
- C++如果两个模板函数都与参数列表匹配,将调用哪个模板
- 用相同的参数声明两个构造函数的最偶像化的方法是什么?
- 当我链接两个静态C++库时,我可以在两个主函数库中有两个主要功能吗?
- 静态类属性,C++中的多个构造函数
- 如何同时创建一个具有两个或多个构造函数初始化的对象
- pair的两个构造函数几乎相同,为什么不生成构建错误?
- 为什么<T> LLVM 中的预期为 Expect&&... 实现两个构造函数<T>?
- 为什么我的类只适用于两个构造函数 C++
- 两个构造函数(带和不带参数),没有输入 -> 没有参数运行。跳过上述类中的构造函数
- 类介绍 (c++) 项目希望我们创建两个构造函数,但它们都不需要任何参数 - 我应该在这里做什么?
- 除了两个构造函数外,C++库导入也可以工作
- 在两个构造函数之前将我的静态数据成员在 CPP 文件中初始化为 0
- 如何有条件地在具有相同签名的两个构造函数之间切换
- RAII 在两个构造函数之间进行选择的方式
- 具有两个构造函数的抽象类
- 这两个构造函数调用之间的区别
- 为什么在我的程序中调用两个构造函数
- 组合复制和移动的两个构造函数
- 为什么这两个构造函数一起不会产生歧义错误?
- 在两个构造函数之间进行选择