为啥用 std::function 重载函数需要中间变量

Posted

技术标签:

【中文标题】为啥用 std::function 重载函数需要中间变量【英文标题】:Why does overloading a function with std::function require an intermediate variable [duplicate]为什么用 std::function 重载函数需要中间变量 【发布时间】:2021-10-14 14:52:34 【问题描述】:
#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);

【问题讨论】:

如果您想要以非传统方式重载事物的能力,您可能会在“重载模式”或您想调用的任何名称中找到用途(我们确实需要一个可搜索的名称) :cppstories.com/2019/02/2lines3featuresoverload.html 编辑后,问题要求一些真正不同的东西。请不要这样做,并要求一个新的。 @Evg 是吗?标题仍然在问为什么我的重载方法失败了,其中的答案(以及重复的建议)仍然有效。通过添加动机(最初已经在问题的正文中),我认为可以从这个重复的问题中获得一些可赎回的价值 这里没有重载。它的目的是让这样一个超载,问一个不同的问题可能会给出更相关的答案。如果问题只是关于隐藏姓名,那么受骗者似乎可以解释发生了什么。 【参考方案1】:

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

std::function&lt;bool()&gt; f1 = std::bind(f1, 1, 2); 中,= 右侧的f1 指的是您在左侧声明的f1

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

【讨论】:

void* ptr = &amp;ptr; 可能是一个定义明确的例子。

以上是关于为啥用 std::function 重载函数需要中间变量的主要内容,如果未能解决你的问题,请参考以下文章

使用 + (unary plus) 为 lambda 解决函数指针和 std::function 上的模棱两可的重载

没有可行的重载'='用于将std :: function回调赋值为成员函数

模板类重载 std::bind 成员函数

C++11 std::bind和std::function解析

带有 std::function 参数的重载运算符

为啥 C++11 不能将不可复制的仿函数移动到 std::function?