问题标签 [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.
c++ - 使用`std::function` 调用非空函数
前段时间我用std::function
的差不多是这样的:
基本上,我这样做是因为我想在 a 中存储不同的函数对象std::function
,但我不想限制这些函数的返回类型。由于这似乎有效,我就同意了。但我不相信它可以安全使用,我也找不到任何关于它的文档。有谁知道这种用法是否合法?或者更一般地说,可以安全地分配给 a 的对象的规则是什么std::function
?
编辑
为了澄清起见,我关心的问题是 lambda 函数返回 an int
,而func
声明为 return type void
。我不确定这是否可以,尤其是在拨打电话后func()
。
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)
):
原因是function
s 构造函数试图从中获取operator ()
(context_binder
即使它没有)。
所以我对这个几乎解决方案的问题是:有什么方法可以让g++
我更喜欢我的弃用运算符而不是尝试使用function
's 构造函数?
c++ - 对 API 使用 std::function(跨模块边界)
很确定我知道这个问题的答案(不认为),但是可以安全地接受/返回std::function
API 中的值(跨模块边界)吗?
我在想“不”,因为我认为不能保证一个供应商的std::function
实施与另一个供应商的实施兼容。是这样吗?
如果我怀疑答案是否定的,那么你们都是如何处理这种事情的?我可能不得不求助于自己的实现,或者只是避免类似的事情std::function
(例如:使用函数指针或函数)。:-( 我发现自己以前在很多情况下都这样做过(重新发明了很多标准 C++ 库,当然遗憾的是,甚至制作了我们自己的符合 STL 的向量类型,同时支持范围 ctor 和填充 ctor、自定义分配器等. 肯定不好玩,我怀疑它是否与标准实现一样好)仅仅是因为可以动态链接到一个库,例如,MSVC 2010 的 std::function 实现来自用 mingw 编写的二进制文件,例如
当然,另一种选择是在我们的 API 中根本不使用这些类型的 C++ 特性,而是使用 C 接口,但这对我们来说代价是相当高的,因为我们使用我们的 API 作为中心 API内部和第三方开发。
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提供它。
c++ - C++:新手的函子和 std::function
我有一个简单的问题,但我不知道如何解决它,因为我从未在 C++ 中使用过函子。
我想做这样的事情(这只是一个例子):
使用 functors/std::functions 的正确语法是什么?
非常感谢你 !
c++ - C++11:如何访问不同类型的 std::functions 目标?
我想编写一个最小的多播委托类。它的接口包含三个运算符 operator() 用于调用委托和 operator+=/operator-= 用于添加/删除可调用类型,如函数、方法、lambda 或仿函数。
我在实现 operator-= 时遇到了麻烦,我需要比较函数目标的地址以进行删除。到目前为止,这是我想出的(我使用 g++ 4.6.3):
当我用以下代码替换 TODO 行时,operator-= 适用于函数:
这是一个最小的例子:
但是,对于其他可调用类型,它会崩溃,因为 std::function.target() 返回空指针。显然模板不再适合,所以我尝试模板 Event::operator-= 但由于“不完整类型”,它不能编译最可调用的类型:
我也尝试过 T* 作为 target() 的模板参数,但我被卡住了。是否可以编写一个通用 operator-= 来正确比较任何可调用类型?
提前致谢!
c++ - 在 std::function 参数上强制执行 const ref
我有一个带有 std::function 参数的函数。我希望 std::function 有一个 bool& 参数:
但是没有强制执行 ref 约束,我可以拥有:
或者
编译器是 MSVC 2010。
注意
第一个示例为 bool 使用了一个 const ref,因为 bool 变量在另一个线程中发生了更改,我需要跟踪其用于 ref 的值。而且我不能在 lambda 中修改它,因此是 const。
c++ - 从 std::function 调用签名推断模板参数
考虑这个模板函数:
为什么编译器不能ReturnT
从传递的调用签名中推断出来?
c++ - Fast Delegate (et al) 背后的想法是否已用于优化 std::function?
已经有关于 C++“委托”的提议,其开销低于boost::function
:
有没有使用这些想法来实现std::function
,从而产生比 更好的性能boost::function
?有没有人比较过std::function
vs的表现boost::function
?
我想专门针对英特尔 64 位架构上的 GCC 编译器和 libstdc++ 了解这一点,但欢迎提供有关其他编译器的信息(例如 Clang)。
c++ - C++11 std::function 和完美转发
为什么 C++ 标准中 std::function<>::operator() 的定义是:
并不是
?
有人会认为,要正确转发参数,我们需要 && ,然后std::forward<ArgTypes>...
在转发调用时在函数体中使用?
我部分重新实现了 std::function 来测试它,我发现如果我使用 &&,当我稍后尝试按值传递参数给 operator() . 我认为我对右值/转发概念有足够的了解,但我仍然无法理解这一点。我错过了什么?