为啥不执行 std::function

Posted

技术标签:

【中文标题】为啥不执行 std::function【英文标题】:why std::function is not executed为什么不执行 std::function 【发布时间】:2022-01-20 18:07:21 【问题描述】:

我正在使用 std::bind 创建一个 std::function 类型并对其进行 typedef,但它的实例不会执行。以下是我的代码:

void func(int a, const std::string& b)

    std::cout << a << ", " << b << std::endl;

typedef std::function<void (int, const std::string&)> THE_FUNCTION;

THE_FUNCTION f = std::bind(func, 18, std::string("hello world"));

f; // no action at all
f(); // will not compile, term does not evaluate to a function taking 0 arguments
     // class does not define an 'operator()' or a user defined conversion operator 
     // to a pointer-to-function or reference-to-function that takes appropriate number 
     // of arguments
f.operator(); // will not compile, 'std::_Func_class<_Ret,int,const std::string &>::operator ()'
              // : non-standard syntax; use '&' to create a pointer to member
(&the_f)->operator(); // will not compile, 'std::_Func_class<_Ret,int,const std::string &>::operator ()': non-standard syntax; use '&' to create a pointer to member

但是如果我这样做,那么函数就会被执行:

auto g = std::bind(func, 3, "good morning")
g()

【问题讨论】:

当您执行void (int, const std::string&amp;) 时,您是在告诉std::funtion 它是operator() 将返回void 并具有参数intconst std::string&amp; 但是如果调用这个函数,整数和字符串都会被打印出来。事实上,没有打印任何东西。我把breaker指针放在func里,并没有停在那里。 f; 是无操作的;你实际上并没有打电话给任何东西。 f() 尝试调用某些东西 - 但正如您所注意到的,它没有编译,因为您告诉 f 期望两个参数但没有传递任何参数。 std::bind(func, 18, std::string("hello world")) 产生一个不带参数的可调用对象;您可能打算将其分配给std::function&lt;void()&gt; 它没有被执行,因为除了一个例子之外,它甚至不会编译。编译的本质上是一个空语句无操作。换句话说,std::function&lt;void()&gt; f = std::bind(func, 18, std::string("hello world"))); 然后f(); 应该可以工作。 再一次,那将是std::function&lt;void()&gt;。注意括号。 【参考方案1】:

改变这个:

typedef std::function<void (int, const std::string&)> THE_FUNCTION; 

与:

typedef std::function<void ()> THE_FUNCTION; 

它会起作用的。

L.E.:当你调用 bind 时,这意味着你有一个与你想要的“非常相似”的函数,并用一些提供的“值”填充其余不需要的参数。

https://en.cppreference.com/w/cpp/utility/functional/bind

【讨论】:

这行得通。谢谢!现在我还有一个问题:void func(int a, const std::string&amp; b) std::cout &lt;&lt; a &lt;&lt; ", " &lt;&lt; b &lt;&lt; std::endl; typedef std::function&lt;void ()&gt; FUNCTION; FUNCTION f = std::bind(func, 1, std::placeholders::_1); 这不会编译。 因为现在您使用的是占位符。这意味着您期望的签名是 std::function FUNCTION;这就是我们首先使用绑定的原因,因为我们可以为现有函数创建自定义函数指针,提供一些值和一些“通过占位符的预期参数”

以上是关于为啥不执行 std::function的主要内容,如果未能解决你的问题,请参考以下文章

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

带有赋值运算符和调用运算符的 std::function 并发

使用 lambda 创建 std::function 会导致多余的 lambda 对象复制 - 为啥?

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

为啥我不能将 lambda 传递给这个需要 std::function 的函数? [复制]

为啥将影响 lambda 的代码编译为 std::function 这么慢,尤其是使用 Clang?