条款34 考虑lambda而非std::bind

server/2024/12/23 7:28:04/

一、lambda比std::bind可读性更高

lambda与正常写一个函数其实没有什么区别,但是std::bind的传入参数是理科调用的

auto setSoundL=[](int x) { setAlarm(steady_clock::now());};
// auto setSoundB=std::bind(setAlarm,steady_clock::now(),_1); //因为是立刻执行,所以需要更改写法
auto setSoundB=std::bind(setAlarm,std::bind(steady_clock::now()),_1);

二、当存在函数重载时std::bind也会存在问题

void func(int a, int b, int c);
void func(int a, int b);auto funcL=[](int b){func(5,b,10);}
auto funcB=std::bind(fun, 5, std::placeholders::_1, 10); //报错
//正确写法
using fun3ParamType=void(*)(int a,int b, int c);
auto funB=std::bind(static_cast<fun3ParamType>(func),5, std::placeholders::_1, 10);

三、功能稍微复杂的情况

auto betweenL=[lowVal, highVal](const auto& val){return lowVal<=val && highVal>=val};auto betweenB=std::bind(std::logic_and<>(),std::bind(std::less_equal<>()),lowVal,_1),std::bind(std::less_equal<>()),_1,highVal));

四、合理使用std::bind

  • C++11不提供移动捕获,可以使用lambda与bind相结合
  • C++11中.bind对象上的函数调用运算符使用完美转发,可接收任意参数,lambda不行

    在 C++11 中,Lambda 表达式的参数列表是固定的,不能直接支持完美转发。但是从 C++14 开始,Lambda 表达式可以通过 auto&& 类型的参数实现完美的参数转发。

    C++11 Lambda 的局限性

    #include <iostream>
    #include <utility> // for std::forward// C++11 Lambda 无法直接支持完美转发
    auto lambda_cxx11 = [](int x) {std::cout << "C++11 Lambda: " << x << '\n';
    };int main() {int a = 42;lambda_cxx11(a); // 工作正常,但不支持完美转发// lambda_cxx11(std::move(a)); // 编译错误:lambda_cxx11 期望的是 lvalue 引用return 0;
    }

    在这个 C++11 的例子中,Lambda 表达式只能接受特定类型的参数(这里是 int),并且不能根据调用时提供的参数类型进行调整。如果尝试传递一个右值(如 std::move(a)),就会导致编译错误,因为 Lambda 的参数列表是固定的,只接受左值引用。

    C++14 Lambda 改进后的完美转发

    #include <iostream>
    #include <utility> // for std::forward// C++14 Lambda 可以使用 auto&& 实现完美转发
    auto lambda_cxx14 = [](auto&& arg) {// 使用 std::forward 将 arg 按其原始值类别转发std::cout << "C++14 Lambda: " << std::forward<decltype(arg)>(arg) << '\n';
    };int main() {int a = 42;lambda_cxx14(a);           // 正常工作,按 lvalue 引用转发lambda_cxx14(std::move(a)); // 也正常工作,按 rvalue 引用转发return 0;
    }

    在这个 C++14 的例子中,Lambda 表达式使用了 auto&& 作为参数类型,这使得它可以接受任何类型的参数,并且通过 std::forward 实现了完美转发。这意味着无论你传递的是左值还是右值,Lambda 都能正确地处理它们,就像 std::bind 一样。

    使用 std::bind 来创建一个绑定对象,该对象将这些参数完美转发给目标函数。

    #include <iostream>
    #include <functional>
    #include <utility> // for std::forward// 定义一个可变参数模板函数,用于打印所有传入的参数
    template<typename... Args>
    void print(Args&&... args) {(std::cout << ... << std::forward<Args>(args)); // C++17 折叠表达式std::cout << '\n';
    }int main() {// 使用 std::bind 创建一个绑定对象,它可以接受任意参数auto bound_print = std::bind(&print<int, double, const char*>, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);// 调用绑定对象,它会将参数完美转发给 print 函数int x = 42;double y = 3.14;const char* z = "Hello";bound_print(x, y, z); // 输出: 423.14Hello// 另一种方式是直接使用占位符,这样可以传递任意数量和类型的参数auto bound_print_any = std::bind(&print<std::string, int>, std::placeholders::_1, std::placeholders::_2);bound_print_any("World", 100); // 输出: World100// 或者完全不指定类型,让编译器推导auto bound_print_all = std::bind(print, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);bound_print_all(10, 20.5, "Test"); // 输出: 1020.5Testreturn 0;
    }
  • C++14之后均可使用lambda表达式

http://www.ppmy.cn/server/152433.html

相关文章

Burp与其他安全工具联动及代理设置教程

Burp Suite 是一款功能强大的 Web 安全测试工具&#xff0c;其流量拦截和调试功能可以与其他安全工具&#xff08;如 Xray、Yakit、Goby 等&#xff09;实现联动&#xff0c;从而提升渗透测试的效率。本文将详细讲解 Burp 与其他工具联动的原理以及代理设置的操作方法&#xff…

工具篇-postman快速导入全局变量设置简单压测

postman 是一款成熟强大的http工具&#xff0c;可以用来发送http请求&#xff0c;还可以写脚本做自动化测试&#xff0c;本文介绍一下几个常用的技巧&#xff1a;将浏览器请求1秒导入到postman &#xff0c;postman全局变量、postman简单压测 chrome浏览器请求导入导入到post…

纯css 实现呼吸灯效果

开始效果 呼吸效果 实现代码 <div class"container"><div class"breathing-light"></div> </div><style>html,body {height: 100%;background-color: white;}.container {padding: 100px;}.container .breathing-light {wi…

sqoop导入hdfs,hive

sqoop将mysql中的表导入到hdfs中 sqoop import \ > --connect jdbc:mysql://192.168.52.150/test \ > --username root \ > --password 123456 \ > --table emp \ > --delete-target-dir \ > --target-dir /sqoop_works/emp_1将数据导入hive中&#xff0c;首…

多进程、多线程、分布式测试支持-pytest-xdis插件

pytest-xdist是pytest测试框架的一个插件&#xff0c;它提供了多进程、多线程和分布式测试的支持&#xff0c;可以显著提高测试效率。以下是对pytest-xdist的详细介绍&#xff1a; 一、安装 要使用pytest-xdist&#xff0c;首先需要安装pytest和pytest-xdist。可以通过pip进行…

国际抖音TikTok矩阵运营的关键要素有哪些?

在全球化的今天&#xff0c;TikTok作为新兴的社交媒体平台&#xff0c;为国际品牌提供了前所未有的营销机遇。通过构建TikTok矩阵&#xff0c;品牌可以迅速扩大国际影响力&#xff0c;精准触达目标受众&#xff0c;提升品牌认知度和用户粘性。本文将详细探讨国际抖音TikTok矩阵…

css代码加密

CSS代码加密是一种手段&#xff0c;目的是保护CSS代码不被轻易查看或修改。然而&#xff0c;需要注意的是&#xff0c;这种加密并不是绝对安全的&#xff0c;因为它可以被解密。以下是一种简单的CSS加密方法&#xff0c;使用了简单的替换加密&#xff1a; function encryptCSS…

C语言入门指南:从零开始的编程之路

记得我刚开始接触编程时,也像很多初学者一样充满疑惑。编程看起来很神奇,但要如何开始呢?经过多年编程经验的积累,今天和大家分享如何入门C语言编程。 C语言诞生于1972年,由Dennis Ritchie在贝尔实验室开发。它的出现彻底改变了计算机编程的历史。虽然现在有很多更新的编程语…