为什么用 std::function 重载函数需要一个中间变量

Why does overloading a function with std::function require an intermediate variable

#include <functional>

bool f1(int a, int b)
{
    return true;
}

int main()
{
    // This compiles
    std::function<bool()> f2 = std::function<bool()>(std::bind(f1, 1, 2));
    std::function<bool()> f1 = f2;

    // These don't compile
    //std::function<bool()> f1 = std::function<bool()>(std::bind(f1, 1, 2));
    //std::function<bool()> f1 = std::bind(f1, 1, 2);
    //std::function<bool()> f1(std::bind(f1, 1, 2));
}

我试图通过提供同名的 std::function 来重载 f1。但是,我 运行 遇到了这种奇怪的情况,其中必须使用中间变量 f2 否则它不会编译。为什么会这样?

3种情况的报错信息如下

error: no matching function for call to ‘std::function<bool()>::function(std::_Bind_helper<false, std::function<bool()>&, int, int>::type)’
     std::function<bool()> f1 = std::function<bool()>(std::bind(f1, 1, 2));
error: conversion from ‘std::_Bind_helper<false, std::function<bool()>&, int, int>::type’ {aka ‘std::_Bind<std::function<bool()>(int, int)>’} to non-scalar type ‘std::function<bool()>’ requested
     std::function<bool()> f1 = std::bind(f1, 1, 2);
                                ~~~~~~~~~^~~~~~~~~~
error: no matching function for call to ‘std::function<bool()>::function(std::_Bind_helper<false, std::function<bool()>&, int, int>::type)’
     std::function<bool()> f1(std::bind(f1, 1, 2));
                                                 ^

编辑 1

看起来即使在第一个编译的情况下,它也没有像我希望的那样完成重载,因为原始 bool f1(int a, int b) 不再可访问。但是我还是很想知道为什么编译器只针对上面的一些情况编译。


编辑2(关闭后)

虽然事实证明这种行为的原因实际上很愚蠢并且与 std::function 无关,但我将尝试通过发布我如何完成我想做的事情来增加一些可挽回的价值:通过命名原始 f1 函数

namespace
{
bool f1(int a, int b)
{
    printf("blah\n");
    return true;
}
}

int main()
{
    // This works
    //std::function<bool()> f2 = std::function<bool()>(std::bind(f1, 1, 2));
    //std::function<bool()> f1 = f2;

    // These work also
    std::function<bool()> f1 = std::function<bool()>(std::bind(::f1, 1, 2));
    //std::function<bool()> f1 = std::bind(::f1, 1, 2);
    //std::function<bool()> f1(std::bind(::f1, 1, 2));
    //
    
    f1();
    ::f1(1,2);
}

变量一经声明就进入作用域。这意味着它们在其初始化程序的范围内。

std::function<bool()> f1 = std::bind(f1, 1, 2);中,=右边的f1指的是你在左边声明的f1

请注意,这绝不是 std::function 或任何东西独有的。 int a = a; 在语法上是完全正确的(尽管它的行为是未定义的)。