问题标签 [std-function]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
3 回答
7627 浏览

c++ - 使用`std::function` 调用非空函数

前段时间我用std::function的差不多是这样的:

基本上,我这样做是因为我想在 a 中存储不同的函数对象std::function,但我不想限制这些函数的返回类型。由于这似乎有效,我就同意了。但我不相信它可以安全使用,我也找不到任何关于它的文档。有谁知道这种用法是否合法?或者更一般地说,可以安全地分配给 a 的对象的规则是什么std::function

编辑

为了澄清起见,我关心的问题是 lambda 函数返回 an int,而func声明为 return type void。我不确定这是否可以,尤其是在拨打电话后func()

0 投票
1 回答
2397 浏览

c++ - C++:获取从 std::bind 产生的参数

首先,有一点背景知识:在我的工作中,我们绑定了稍后调用的回调,这使得尝试通过日志跟踪控制流变得非常困难。为了帮助实现这一点,我们使用“日志上下文”,让您可以在请求通过系统时对其进行跟踪。您可以使用静态函数复制当前上下文并使用静态函数log_context::get_current恢复它log_context::set_current。这导致每次我们将回调发布到工作队列时都会导致大量重复代码。

我想做一个函数,它是一个替换的函数std::bind,它将保存当前log_context并在调用时恢复它。但是,我在编写它时遇到了一些麻烦。

现在,该函数如下所示:

它有效,但问题是用法要求您无缘无故地传递函数类型(除了这就是我找出用途的方式TFuncArgs):

所以,不是一个简单的替代品。似乎应该在编译时知道这些信息,我只是不知道如何。它几乎就在那里如何消除传递函数类型的需要?


我最初的想法是将绑定从将其转换为如下函数:

问题是 cast ( operator std::function<TReturn (TFuncArgs...)>() const) 永远不会被调用 (given int foo(int x, int y, int z)):

原因是functions 构造函数试图从中获取operator ()context_binder即使它没有)。

所以我对这个几乎解决方案的问题是:有什么方法可以让g++我更喜欢我的弃用运算符而不是尝试使用function's 构造函数?

0 投票
1 回答
1779 浏览

c++ - 对 API 使用 std::function(跨模块边界)

很确定我知道这个问题的答案(不认为),但是可以安全地接受/返回std::functionAPI 中的值(跨模块边界)吗?

我在想“不”,因为我认为不能保证一个供应商的std::function实施与另一个供应商的实施兼容。是这样吗?

如果我怀疑答案是否定的,那么你们都是如何处理这种事情的?我可能不得不求助于自己的实现,或者只是避免类似的事情std::function(例如:使用函数指针或函数)。:-( 我发现自己以前在很多情况下都这样做过(重新发明了很多标准 C++ 库,当然遗憾的是,甚至制作了我们自己的符合 STL 的向量类型,同时支持范围 ctor 和填充 ctor、自定义分配器等. 肯定不好玩,我怀疑它是否与标准实现一样好)仅仅是因为可以动态链接到一个库,例如,MSVC 2010 的 std::function 实现来自用 mingw 编写的二进制文件,例如

当然,另一种选择是在我们的 API 中根本不使用这些类型的 C++ 特性,而是使用 C 接口,但这对我们来说代价是相当高的,因为我们使用我们的 API 作为中心 API内部和第三方开发。

0 投票
1 回答
710 浏览

c++ - 作为 std::function 参数传递的 C++11 lambda - 在返回类型上调度

场景:

我们有一个具有通用错误处理接口的 API。它是一个 C API,所以它告诉我们,在调用每个 API 函数之后,我们需要执行一些样板文件,如下所示:

你显然讨厌重复自己,所以你想把这个处理封装在一个宏中,这样你就可以编写如下代码:

您也可以从面向方面编程的角度来考虑这一点 - 想象一下宏添加了日志记录,将信息发送到远程监视器等等......关键是它应该封装一个表达式,在它周围做任何事情,然后返回表达式返回的任何类型 - 当然表达式可能不会返回任何内容

这意味着你不能只是做

...因为在某些情况下,表达式不会返回任何内容!

那么......你会怎么做呢?

请不要建议将完整的语句封装在宏中......

...因为这永远不会适用于以下内容:

...你吞没了所有的 if 语句?它的动作包括其他 API 调用,所以……宏中的宏?调试简直成了地狱。

我自己的尝试如下,使用 lambdas 和 std::function - 但它可以说是丑陋的......我无法将表达式的 lambda 直接传递给采用 std::function 的模板(根据 lambda 的返回进行专门化类型),所以代码变得相当讨厌。

你能想出更好的方法吗?

更新,KennyTM 优秀解决方案的附录

我在这里放置了触发这个问题的实际 OpenGL 代码。如您所见,错误检查代码不仅仅是打印 - 它还引发了用户代码可以处理的异常。我添加这个附录是为了注意使用 KennyTM 的解决方案,你最终会从析构函数中抛出这个异常,这没关系(继续阅读):

C++ FAQ中解释了可以从此析构函数中抛出的原因:

C++ 规则是,您决不能从在另一个异常的“堆栈展开”过程中调用的析构函数中抛出异常……您可以说在处理另一个异常时永远不要从析构函数中抛出异常

在我们的例子中,我们希望用户代码(调用特殊宏)来处理异常;所以我们需要确定我们在ErrorChecker 的析构函数中的“抛出”是第一个——即实际调用的C API 永远不会抛出。这很容易用这种形式完成:

这种形式的宏保证了实际的 C API(通过VA_ARGS 调用)永远不会抛出 - 因此,ErrorChecker 的析构函数中的“抛出”将始终是第一个这样做的。

所以这个解决方案涵盖了我最初问题的所有角度 - 非常感谢Alexander Turner提供它。

0 投票
2 回答
3471 浏览

c++ - C++:新手的函子和 std::function

我有一个简单的问题,但我不知道如何解决它,因为我从未在 C++ 中使用过函子。

我想做这样的事情(这只是一个例子):

使用 functors/std::functions 的正确语法是什么?

非常感谢你 !

0 投票
1 回答
1959 浏览

c++ - C++11:如何访问不同类型的 std::functions 目标?

我想编写一个最小的多播委托类。它的接口包含三个运算符 operator() 用于调用委托和 operator+=/operator-= 用于添加/删除可调用类型,如函数、方法、lambda 或仿函数。

我在实现 operator-= 时遇到了麻烦,我需要比较函数目标的地址以进行删除。到目前为止,这是我想出的(我使用 g++ 4.6.3):

当我用以下代码替换 TODO 行时,operator-= 适用于函数:

这是一个最小的例子:

但是,对于其他可调用类型,它会崩溃,因为 std::function.target() 返回空指针。显然模板不再适合,所以我尝试模板 Event::operator-= 但由于“不完整类型”,它不能编译最可调用的类型:

我也尝试过 T* 作为 target() 的模板参数,但我被卡住了。是否可以编写一个通用 operator-= 来正确比较任何可调用类型?

提前致谢!

0 投票
0 回答
984 浏览

c++ - 在 std::function 参数上强制执行 const ref

我有一个带有 std::function 参数的函数。我希望 std::function 有一个 bool& 参数:

但是没有强制执行 ref 约束,我可以拥有:

或者

编译器是 MSVC 2010。

注意

第一个示例为 bool 使用了一个 const ref,因为 bool 变量在另一个线程中发生了更改,我需要跟踪其用于 ref 的值。而且我不能在 lambda 中修改它,因此是 const。

0 投票
3 回答
2655 浏览

c++ - 从 std::function 调用签名推断模板参数

考虑这个模板函数:

为什么编译器不能ReturnT从传递的调用签名中推断出来?

0 投票
2 回答
3042 浏览

c++ - Fast Delegate (et al) 背后的想法是否已用于优化 std::function?

已经有关于 C++“委托”的提议,其开销低于boost::function

有没有使用这些想法来实现std::function,从而产生比 更好的性能boost::function?有没有人比较过std::functionvs的表现boost::function

我想专门针对英特尔 64 位架构上的 GCC 编译器和 libstdc++ 了解这一点,但欢迎提供有关其他编译器的信息(例如 Clang)。

0 投票
1 回答
3357 浏览

c++ - C++11 std::function 和完美转发

为什么 C++ 标准中 std::function<>::operator() 的定义是:

并不是

?

有人会认为,要正确转发参数,我们需要 && ,然后std::forward<ArgTypes>...在转发调用时在函数体中使用?

我部分重新实现了 std::function 来测试它,我发现如果我使用 &&,当我稍后尝试按值传递参数给 operator() . 我认为我对右值/转发概念有足够的了解,但我仍然无法理解这一点。我错过了什么?