草庐IT

c++ - std::function 的解释

coder 2024-01-31 原文

std::function 的目的是什么?据我所知,std::function 将函数、仿函数或 lambda 转换为函数对象。

我不太明白这样做的目的...Lambdas 和 Functors 都已经是函数对象,我相信它们可以用作排序和转换等算法的谓词。作为旁注,Lambda 实际上是仿函数(内部)。所以我唯一能看到 std::function 有用的是将常规函数转换为函数对象。

而且我也不明白为什么要将常规函数转换为函数对象。如果我想使用一个函数对象,我会首先将一个作为仿函数或 lambda...而不是编写一个函数,然后用 std::function 转换它,然后将它作为谓词传递...

我猜 std::function 还有很多东西……乍一看不是很明显。

std::function 的解释将不胜感激。

最佳答案

What is the purpose of std::function? As far as I understand, std::function turns a function, functor, or lambda into a function object.

std::function是一个更广泛的概念的例子,称为类型删除。你的描述不太准确。什么std::function<void()>确实,为了选择一个特定的特化,代表任何 可以不带参数调用的可调用对象。它可以是函数指针或具有具体类型的函数对象,或从 lambda 构建的闭包。源类型是什么并不重要,只要它符合契约(Contract)——它就可以工作。我们不使用具体的源类型,而是“删除”它 - 我们只处理 std::function .

现在,我们为什么要使用类型删除?毕竟,难道我们没有模板可以直接使用具体类型吗?那岂不是更高效而且 C++ 不就是关于效率的吗?!

有时,您不能使用具体类型。一个可能更熟悉的例子是常规的面向对象的多态性。为什么我们要存储 Base*当我们可以存储 Derived* 时?好吧,也许我们不能存储 Derived* .也许我们有很多不同的Derived*是不同用户使用的。也许我们正在编写一个甚至不知道 Derived 的库.这也是 类型删除,只是与std::function 不同的技术。使用。

用例的非详尽列表:

  • 需要存储一个潜在的异构对象列表,而我们只关心它们是否满足一个具体的接口(interface)。对于 std::function ,也许我只有一个 std::vector<std::function<void()>> callbacks - 它们可能都有不同的具体类型,但我不在乎,我只需要调用它们。
  • 需要跨 API 边界使用(例如,我可以有一个 virtual 函数接受一个 std::function<void()> ,但我不能有一个 virtual 函数模板)。
  • 从工厂函数返回 - 我们只需要一些满足某些概念的对象,我们不需要具体的东西(同样,在 OO 多态性中很常见,这也是类型删除)。
  • 实际上可以在任何地方使用模板,但性能提升不值得编译。

关于c++ - std::function 的解释,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51934866/

有关c++ - std::function 的解释的更多相关文章

  1. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  2. ruby - 有人可以帮助解释类创建的 post_initialize 回调吗 (Sandi Metz) - 2

    我正在阅读SandiMetz的POODR,并且遇到了一个我不太了解的编码原则。这是代码:classBicycleattr_reader:size,:chain,:tire_sizedefinitialize(args={})@size=args[:size]||1@chain=args[:chain]||2@tire_size=args[:tire_size]||3post_initialize(args)endendclassMountainBike此代码将为其各自的属性输出1,2,3,4,5。我不明白的是查找方法。当一辆山地自行车被实例化时,因为它没有自己的initialize方法

  3. ruby - 使用 `+=` 和 `send` 方法 - 2

    如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:

  4. ruby - 如何计算 Liquid 中的变量 +1 - 2

    我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我

  5. ruby - 解释为局部变量会覆盖方法名称吗? - 2

    如thisquestion,当在其自己的赋值中使用未定义的局部变量时,它的计算结果为nil。x=x#=>nil但是当局部变量的名称与现有的方法名称冲突时,就比较棘手了。为什么下面的最后一个示例返回nil?{}.instance_eval{a=keys}#=>[]{}.instance_eval{keys=self.keys}#=>[]{}.instance_eval{keys=keys}#=>nil 最佳答案 在Ruby中,因为可以在没有显式接收器和括号的情况下调用方法,所以在局部变量引用和无接收器无参数方法调用之间存在语法歧义:f

  6. 语法类似于 GitHub Flavored Markdown 的 Ruby markdown 解释器? - 2

    我使用Jekyll运行博客,并认为我会解决RedcarpetMarkdown解释器,因为它是developedandusedbyGitHub.好吧,我只是碰巧遇到了一个错误,去检查问题,然后foundthis.Maintainersays,"Asyouprobablyhavenoticed(harharharhar)Idon'thavetimetomaintainRedcarpetanymore.It'snotapriorityforme(IfindMarkdownthoroughlyboring)andit'snotapriorityforGitHub,becausewenolong

  7. arrays - Ruby 数组 += vs 推送 - 2

    我有一个数组数组,想将元素附加到子数组。+=做我想做的,但我想了解为什么push不做。我期望的行为(并与+=一起工作):b=Array.new(3,[])b[0]+=["apple"]b[1]+=["orange"]b[2]+=["frog"]b=>[["苹果"],["橙子"],["Frog"]]通过推送,我将推送的元素附加到每个子数组(为什么?):a=Array.new(3,[])a[0].push("apple")a[1].push("orange")a[2].push("frog")a=>[[“苹果”、“橙子”、“Frog”]、[“苹果”、“橙子”、“Frog”]、[“苹果”、“

  8. += 的 Ruby 方法 - 2

    有没有办法让Ruby能够做这样的事情?classPlane@moved=0@x=0defx+=(v)#thisiserror@x+=v@moved+=1enddefto_s"moved#{@moved}times,currentxis#{@x}"endendplane=Plane.newplane.x+=5plane.x+=10putsplane.to_s#moved2times,currentxis15 最佳答案 您不能在Ruby中覆盖复合赋值运算符。任务在内部处理。您应该覆盖+,而不是+=。plane.a+=b与plane.a=

  9. ruby - Sinatra + Heroku + Datamapper 使用 dm-sqlite-adapter 部署问题 - 2

    出于某种原因,heroku尝试要求dm-sqlite-adapter,即使它应该在这里使用Postgres。请注意,这发生在我打开任何URL时-而不是在gitpush本身期间。我构建了一个默认的Facebook应用程序。gem文件:source:gemcuttergem"foreman"gem"sinatra"gem"mogli"gem"json"gem"httparty"gem"thin"gem"data_mapper"gem"heroku"group:productiondogem"pg"gem"dm-postgres-adapter"endgroup:development,:t

  10. ruby - 有人可以解释一下在 Ruby 中注入(inject)的真实、通俗易懂的用法吗? - 2

    我正在学习Ruby,遇到了inject。我正处于理解它的风口浪尖,但当我是那种需要真实世界的例子来学习一些东西的人时。我遇到的最常见的例子是人们使用inject来添加一个(1..10)范围的总和,我不太关心这个。这是一个任意的例子。在实际程序中我会用它做什么?我正在学习,所以我可以继续使用Rails,但我不必有一个以Web为中心的示例。我只需要一些我可以全神贯注的目标。谢谢大家。 最佳答案 inject有时可以通过它的“其他”名称reduce更好地理解。它是一个对Enumerable进行操作(迭代一次)并返回单个值的函数。它有许多有

随机推荐