草庐IT

C++ 11 绑定(bind) std::function 与存储元组和解包

coder 2024-02-25 原文

首先,我对 C++11 还是比较陌生,所以如果我遗漏了什么,请原谅我的疏忽。所以我想做的基本上是让调用者传入一个函数和该函数的任意参数,将其存储起来,然后稍后异步调用它。似乎有 2 个主要选项:

  • 使用 std::bind 将 std::function 绑定(bind)到它的参数(使用可变参数模板获得),然后稍后调用它
  • 将参数包转换为一个元组,存储它和 std::function,然后再次将元组解压为多个参数并使用它调用函数

问题是,一种方法比另一种更好吗?两者之间有优缺点/性能优势吗?

谢谢!

编辑:根据要求,这里有一个澄清,第一种情况是更早的绑定(bind),我将 args 绑定(bind)到函数,只要调用者传递它们,我存储绑定(bind)的 func 以供稍后调用。第二种情况是我分别存储 func 和 args,然后在必须调用函数时使用 args 调用函数。所以问题是性能/代码大小/样式/等哪个更好?

最佳答案

接受 std::function<...>使用适当的签名,将其存储以供稍后回调。让调用者决定他们喜欢如何创建/填充参数。例如,

#include <functional>
#include <iostream>

std::function<int(int)> stored_f;

void set_callback(std::function<int(int)> f) {
    stored_f = std::move(f);
}

void run_the_callback(int value) {
    std::cout << stored_f(value) << '\n';
}

int f(int i) {
    return i + 1;
}

int g(int a, int b) {
    return a + b;
}

int main() {
    // Plain old function pointer
    set_callback(f);
    run_the_callback(1);
    // Use std::bind
    set_callback(std::bind(g, 2, std::placeholders::_1));
    run_the_callback(2);
    // Use a lambda
    set_callback([](int i){ return f(i) * g(i, i);});
    run_the_callback(3);
}

最佳性能 - 如果您不绝对需要回调的类型删除 - 将在仿函数类型上参数化您的代码。例如:

#include <functional>
#include <iostream>

template <typename Functor>
void do_stuff_and_callback_sometimes(Functor f) {
    std::cout << f(1) << '\n';
    // do some stuff, then
    std::cout << f(2) << '\n';
    // more work, and finally
    std::cout << f(3) << "\n\n";
}

int f(int i) {
    return i + 1;
}

int g(int a, int b) {
    return a + b;
}

int main() {
    // Plain old function pointer
    do_stuff_and_callback_sometimes(f);
    // Use std::bind
    do_stuff_and_callback_sometimes(std::bind(g, 2, std::placeholders::_1));
    // Use a lambda
    do_stuff_and_callback_sometimes([](int i){ return f(i) * g(i, i);});
}

在某些情况下避免类型删除是不可能的,而在其他情况下则需要您跳过障碍。这样做是否值得要视情况而定。

关于C++ 11 绑定(bind) std::function 与存储元组和解包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20981376/

有关C++ 11 绑定(bind) std::function 与存储元组和解包的更多相关文章

  1. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

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

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

  3. ruby - ruby 中的 TOPLEVEL_BINDING 是什么? - 2

    它不等于主线程的binding,这个toplevel作用域是什么?此作用域与主线程中的binding有何不同?>ruby-e'putsTOPLEVEL_BINDING===binding'false 最佳答案 事实是,TOPLEVEL_BINDING始终引用Binding的预定义全局实例,而Kernel#binding创建的新实例>Binding每次封装当前执行上下文。在顶层,它们都包含相同的绑定(bind),但它们不是同一个对象,您无法使用==或===测试它们的绑定(bind)相等性。putsTOPLEVEL_BINDINGput

  4. ruby - Rack:如何将 URL 存储为变量? - 2

    我正在编写一个简单的静态Rack应用程序。查看下面的config.ru代码:useRack::Static,:urls=>["/elements","/img","/pages","/users","/css","/js"],:root=>"archive"map'/'dorunProc.new{|env|[200,{'Content-Type'=>'text/html','Cache-Control'=>'public,max-age=6400'},File.open('archive/splash.html',File::RDONLY)]}endmap'/pages/search.

  5. 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.你能做的最好的事情是:

  6. ruby - 安装libv8(3.11.8.13)出错,Bundler无法继续 - 2

    运行bundleinstall后出现此错误:Gem::Package::FormatError:nometadatafoundin/Users/jeanosorio/.rvm/gems/ruby-1.9.3-p286/cache/libv8-3.11.8.13-x86_64-darwin-12.gemAnerroroccurredwhileinstallinglibv8(3.11.8.13),andBundlercannotcontinue.Makesurethat`geminstalllibv8-v'3.11.8.13'`succeedsbeforebundling.我试试gemin

  7. ruby-on-rails - 创建 ruby​​ 数据库时惰性符号绑定(bind)失败 - 2

    我正在尝试在Rails上安装ruby​​,到目前为止一切都已安装,但是当我尝试使用rakedb:create创建数据库时,我收到一个奇怪的错误:dyld:lazysymbolbindingfailed:Symbolnotfound:_mysql_get_client_infoReferencedfrom:/Library/Ruby/Gems/1.8/gems/mysql2-0.3.11/lib/mysql2/mysql2.bundleExpectedin:flatnamespacedyld:Symbolnotfound:_mysql_get_client_infoReferencedf

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

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

  9. ruby-on-rails - 为什么在 Rails 5.1.1 中删除了 session 存储初始化程序 - 2

    我去了这个website查看Rails5.0.0和Rails5.1.1之间的区别为什么5.1.1不再包含:config/initializers/session_store.rb?谢谢 最佳答案 这是删除它的提交:Setupdefaultsessionstoreinternally,nolongerthroughanapplicationinitializer总而言之,新应用没有该初始化器,session存储默认设置为cookie存储。即与在该初始值设定项的生成版本中指定的值相同。 关于

  10. ruby-on-rails - 尝试设置 Amazon 的 S3 存储桶 : 403 Forbidden error & setting permissions - 2

    我正在关注Hartl的railstutorial.org并已到达11.4.4:Imageuploadinproduction.我做了什么:注册亚马逊网络服务在AmazonIdentityandAccessManagement中,我创建了一个用户。用户创建成功。在AmazonS3中,我创建了一个新存储桶。设置新存储桶的权限:权限:本教程指示“授予上一步创建的用户读写权限”。但是,在存储桶的“权限”下,未提及新用户名。我只能在每个人、经过身份验证的用户、日志传送、我和亚马逊似乎根据我的名字+数字创建的用户名之间进行选择。我已经通过选择经过身份验证的用户并选中了上传/删除和查看权限的框(而不

随机推荐