c++ - std::bind 的返回类型可隐式转换为两个不同的显式构造函数

标签 c++ c++11 std-function stdbind

给定两个 explicit 构造函数重载(基于不同的std::function<...>类型),std::bind的返回值能够选择任一个(从而使调用不明确)

call of overloaded ‘Bar(std::_Bind_helper<false, void (Foo::*)(int), 
    Foo*, int>::type)’ is ambiguous

如果我注释掉其中任何一个,代码就会编译!

我本来想制作构造函数 explicit会选择正确的重载,还是会阻止两者都被选中?

当然显式创建std::function在我绑定(bind)作品的时候:

    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() 的结果肯定不是 std::function<Signature> ,即它与您的任何一个构造函数都不完全匹配。因为有一个非 explicit std::function<Signature> 的构造函数它适用于函数对象,两个签名都匹配:生成的绑定(bind)表达式不需要任何参数但它可以接受参数,即任何参数类型也不能用于区分 Bar 的两个构造函数中的哪一个。应该匹配。即使绑定(bind)表达式需要一个参数,我也不认为它会被用来优先选择一个构造函数而不是另一个构造函数。

关于c++ - std::bind 的返回类型可隐式转换为两个不同的显式构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18939107/

相关文章:

c++ - Cygwin GCC 与 Visual Studio 库链接

c++ - 在 C++ 中从 vector 中弹出一个特定元素

c++ - 来自 iso C++ n3290 : Argument dependant Name Lookup: 的一个点

c++ - 关于C++中的动态内存

c++ - 在构造函数中将类成员函数分配给映射

c++ - 在C++中的类中实现回调函数

c++ - 返回对此的引用时出现意外的 std::ostream 输出

c++ - boost::factory 和 std::function

c++ - std::function 是否允许在其返回类型中从引用到拷贝进行隐式转换?

c++ - 在某些东西本身变得线程安全之前,你要走多远?