当前位置: 首页 > wzjs >正文

一个人做网站时间专业软文发稿平台

一个人做网站时间,专业软文发稿平台,郑州企业型网站建设,wordpress占用内存高基础介绍 c17版本引入了std::invoke特性,这是一个通用的调用包装器,可以统一调用: 普通函数成员函数函数对象Lambda表达式指向成员的指针 它的主要作用是提供一个统一的方式来调用各种可调用对象。 std::invoke依赖的头文件:#…

基础介绍

c++17版本引入了std::invoke特性,这是一个通用的调用包装器,可以统一调用:

  • 普通函数
  • 成员函数
  • 函数对象
  • Lambda表达式
  • 指向成员的指针

它的主要作用是提供一个统一的方式来调用各种可调用对象

std::invoke依赖的头文件:#include <functional>

基本用法

下面将详细介绍基本用法,即对上节中提到的对象(普通函数、成员函数、函数对象、Lambda表达式等)的调用。

#include <functional>
#include <iostream>
using namespace std;//普通函数
void basic_function(int x)
{cout <<" 普通函数:"<<x<<endl;
}//具有返回值的普通函数
int add(int a, int b) 
{return a + b;
}//成员函数
class MyClass{public:void member_function(int x){cout <<"成员函数:"<<x<<endl;}int value = 33;
}//函数对象
class Functor
{public:void operator()(int x){cout <<"仿函数对象"<<x<<endl;}
}//示例函数
void basic_usage()
{//调用普通函数std::invoke(basic_function, 5);//调用具有返回值的普通函数int value = std::invoke(add, 4, 5);//调用成员函数MyClass obj;std::invoke(&MyClass::member_function, obj, 5);//调用仿函数对象Functor funtor;std::invoke(funtor, 5);//调用lambda表达式std::invoke([](int x){cout <<"lambda表达式:"<<x<<endl;
}, 5);//访问成员变量,这个成员变量必须时public的std::invoke(&Myclass::value, obj);
}

特性总结

通过上面示例可以得到以下结论:

  • std::invoke表示函数调用:只要调用std::invoke,且执行了这个语句,那么就相当于调用了传入的函数对象
  • std::invoke的含义传入一个函数对象及这个函数对象的参数,然后通过std::invoke完成这个函数的调用

思考:为什么引入std::invoke?

统一的调用语法

函数对象有多种,比如普通函数,成员函数、仿函数对象,lambda表达式等不同的形式,不同的函数对象的调用方法都不相同,请看下面的例子:

#include <functional>
#include <iostream>class Example {
public:void method(int x) {std::cout << "Method called: " << x << "\n";}int value = 42;
};void normal_function(int x) {std::cout << "Function called: " << x << "\n";
}void unified_call_syntax() {Example obj;// 不使用 std::invoke 时的不同调用语法normal_function(1);           // 普通函数调用obj.method(2);               // 成员函数调用int val = obj.value;         // 成员变量访问// 使用 std::invoke 的统一语法std::invoke(normal_function, 1);          // 普通函数std::invoke(&Example::method, obj, 2);    // 成员函数std::invoke(&Example::value, obj);        // 成员变量
}

从上面的例子可以看到,如果不使用std::invoke,那么不同的函数对象的对象方法和形式各不相同;但是引入std::invoke后,可以很明显的看到针对不同的函数对象实现了相同的调用形式。

泛型编程的支持

前面的例子是针对不同的函数对象不同调用,但是提到泛型编程,就会涉及不同的函数对象,不同的参数数量和类型。那如何设计一个函数可以实现不同的函数对象类型,不同参数数量和参数类型的调用呢?首先肯定是需要依靠模板实现的。请看下面的例子:

#include <functional>
#include <iostream>
#include <type_traits>//函数模板
template<typename F, typename... Args>
decltype(auto) modern_call(F&& f, Args&&... args)
{return std::invoke(std::forward<F>(f),std::forward<Args>(args));
}//普通函数
void normal_function(int x) 
{std::cout << "Function called: " << x << "\n";
}
//示范类
class Calculator {
public:int add(int a, int b) { return a + b; }double factor = 1.5;
};void example() {Calculator calc;// 可以统一处理各种可调用对象modern_call(normal_function, 1);                  // 普通函数modern_call(&Calculator::add, calc, 2, 3);       // 成员函数modern_call(&Calculator::factor, calc);          // 成员变量modern_call([](int x) { return x * 2; }, 5);    // lambda表达式
}

通过上面的例子可以看到,通过modern_call的封装,实现了不同类型的函数对象的统一调用。可以这样说,若要实现对不同函数对象的统一调用的支持,必须要依靠模板的方式实现对std::invoke的封装。那这种泛型编程的应用场景有哪些呢?

  • 回调系统
  • 事件系统
  • 命令模式

具体请看下面的例子:

#include <functional>
#include <iostream>
#include <vector>
#include <string>// 1. 事件系统
class EventSystem {
public:template<typename F, typename... Args>void trigger(F&& handler, Args&&... args) {std::invoke(std::forward<F>(handler),std::forward<Args>(args)...);}
};// 2. 命令模式
class Command {std::function<void()> action;
public:template<typename F, typename... Args>Command(F&& f, Args&&... args) {action = [=]() {std::invoke(f, args...);};}void execute() { action(); }
};// 3. 回调系统
class CallbackSystem {
public:template<typename Callback, typename... Args>void registerCallback(Callback&& cb, Args&&... args) {callbacks.emplace_back([=]() {std::invoke(cb, args...);});}void executeAll() {for (auto& callback : callbacks) {callback();}}private:std::vector<std::function<void()>> callbacks;
};

通过上面的例子可以清楚的看到各种场景下的使用方法,但是相同点都是在函数内部都是通过定义函数模板(泛型编程)实现的。

支持智能指针和引用包装器

#include <functional>
#include <memory>
#include <iostream>class Service {
public:int process(int x) { return x * 2; }
};void smart_pointer_example() {// 智能指针支持auto ptr = std::make_shared<Service>();auto unique = std::make_unique<Service>();// std::invoke 可以直接使用智能指针int result1 = std::invoke(&Service::process, ptr, 10);int result2 = std::invoke(&Service::process, unique, 20);// 引用包装器支持Service service;auto ref = std::ref(service);int result3 = std::invoke(&Service::process, ref, 30);
}

总结

我们需要有两个认识:

  1. std::invoke可以实现对函数对象的调用,达到与直接调用函数相同的效果
  2. 如果要实现类似回调系统、事件系统类似的功能,需要集合模板来实现
http://www.dtcms.com/wzjs/483558.html

相关文章:

  • 贵阳网站建设推广最新的网络营销的案例
  • 建立网络专题网站架构网络推广最好的网站有哪些
  • 大同格泰网站建设百度百度百度一下
  • 做外贸网站推广的步骤seo关键词推广方式
  • 做网站推广选哪家关键词排名优化流程
  • 做党务工作常用到的网站百度浏览器下载安装
  • 网站做成app客户端游戏推广员上班靠谱吗
  • 手机网站要素百度网盘登录
  • k8team wordpressseo管理系统培训运营
  • 网页升级访问狼在线观看被公司优化掉是什么意思
  • 菏砖网站建设成都互联网公司排名
  • 企业云网站建设如何建立自己的网站?
  • 怎么设置网站关键字长沙好的seo外包公司
  • wps哪个工具做网站steam交易链接怎么用
  • 17网一起做网店网站谷歌账号注册
  • wordpress 树形页面海阳seo排名
  • seo排名优化北京顺德搜索seo网络推广
  • 关于绿色环保网站的建设历程传媒网站
  • 贵州建设厅监理协会网站百度推广后台
  • 个人主页网站制作免费营销型网站的类型
  • 网站的功能与建设方案sem是什么方法
  • 模板网站做外贸好不好整合营销名词解释
  • 西宁网站设计建设公众号软文素材
  • 公司需要网站 该怎么做一键优化大师
  • 樟木头镇做网站谷歌下载官网
  • 投资做任务赚钱的网站百度问答下载安装
  • 上海 网站建设网络广告图片
  • 克州建设工程信息网免费seo在线优化
  • 快云助手网站建设视频教程手机优化大师官方版
  • 南阳微网站制作百度官方电话24小时