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

怎么用vps的linux做网站搜索引擎优化seo多少钱

怎么用vps的linux做网站,搜索引擎优化seo多少钱,服装设计网页,柳州正规网站制作公司可调用对象包装器, 绑定器 可调用对象 可调用对象是指在 C 中能够像函数一样被调用的实体。它包括了多种类型的对象,使得它们能够像函数一样被调用,可以是函数、函数指针、函数对象、Lambda 表达式等。在C中,具有以下特征之一的实体都被认为…

可调用对象包装器, 绑定器

可调用对象

可调用对象是指在 C++ 中能够像函数一样被调用的实体。它包括了多种类型的对象,使得它们能够像函数一样被调用,可以是函数、函数指针、函数对象、Lambda 表达式等。在C++中,具有以下特征之一的实体都被认为是可调用对象:

1.函数: 常规的函数,包括全局函数和类的成员函数。

void regularFunction(int x) {// ...
}

2.函数指针: 指向函数的指针。

#include <iostream>// 函数原型
void sayHello(const char* name) {std::cout << "Hello, " << name << "!" << std::endl;
}int main() {// 定义函数指针并初始化为指向 sayHello 函数void (*helloFunctionPointer)(const char*) = sayHello;// 使用函数指针调用函数helloFunctionPointer("Alice");helloFunctionPointer("Bob");return 0;
}

3.函数对象: 重载了函数调用运算符 operator() 的类。(仿函数)

#include <iostream>// 函数对象类
struct Functor {int operator()(int x, int y) {return x + y;}
};int main() {// 创建函数对象的实例Functor adder;// 使用函数对象int result = adder(3, 4);std::cout << "Result: " << result << std::endl;return 0;
}

4.Lambda表达式: 匿名的函数对象。

#include <iostream>int main() {// Lambda 表达式,接受一个整数参数并返回它的平方auto square = [](int x) {return x * x;};// 调用 Lambda 表达式int result = square(5);std::cout << "Square of 5 is: " << result << std::endl;return 0;
}

5.类的成员函数指针: 指向类的成员函数或对象的指针。

#include <iostream>
#include <string>
#include <vector>
using namespace std;struct Test
{void print(int a, string b){cout << "name: " << b << ", age: " << a << endl;}int m_num;
};int main(void)
{// 定义类成员函数指针指向类成员函数void (Test::*func_ptr)(int, string) = &Test::print;// 类成员指针指向类成员变量int Test::*obj_ptr = &Test::m_num;Test t;// 通过类成员函数指针调用类成员函数(t.*func_ptr)(19, "Monkey D. Luffy");// 通过类成员指针初始化类成员变量t.*obj_ptr = 1;cout << "number is: " << t.m_num << endl;return 0;
}

在上面的例子中满足条件的这些可调用对象对应的类型被统称为可调用类型。C++中的可调用类型虽然具有比较统一的操作形式,但定义方式五花八门,这样在我们试图使用统一的方式保存,或者传递一个可调用对象时会十分繁琐。现在,C++11通过提供std::function 和 std::bind统一了可调用对象的各种操作。

可调用对象包装器

std::function是可调用对象的包装器。它是一个类模板,可以容纳除了类成员(函数)指针之外的所有可调用对象。通过指定它的模板参数,它可以用统一的方式处理函数、函数对象、函数指针,并允许保存和延迟执行它们。

基本用法

std::function必须要包含一个叫做functional的头文件,可调用对象包装器使用语法如下:

#include <functional>
std::function<返回值类型(参数类型列表)> diy_name = 可调用对象;

下面的实例代码中演示了可调用对象包装器的基本使用方法:

#include <iostream>
#include <functional>
using namespace std;int add(int a, int b)
{cout << a << " + " << b << " = " << a + b << endl;return a + b;
}class T1
{
public:static int sub(int a, int b){cout << a << " - " << b << " = " << a - b << endl;return a - b;}
};class T2
{
public:int operator()(int a, int b){cout << a << " * " << b << " = " << a * b << endl;return a * b;}
};int main(void)
{// 绑定一个普通函数function<int(int, int)> f1 = add;// 绑定以静态类成员函数function<int(int, int)> f2 = T1::sub;// 绑定一个仿函数T2 t;function<int(int, int)> f3 = t;// 函数调用f1(9, 3);f2(9, 3);f3(9, 3);return 0;
}

输入结果如下:

9 + 3 = 12
9 - 3 = 6
9 * 3 = 27

通过测试代码可以得到结论:std::function可以将可调用对象进行包装,得到一个统一的格式,包装完成得到的对象相当于一个函数指针,和函数指针的使用方式相同,通过包装器对象就可以完成对包装的函数的调用了。

作为回调函数使用

因为回调函数本身就是通过函数指针实现的,使用对象包装器可以取代函数指针的作用,来看一下下面的例子:

#include <iostream>
#include <functional>
using namespace std;// 模拟某个异步操作
void performAsyncOperation(function<void()> callback) {// 模拟异步操作完成后调用回调函数std::cout << "Async operation completed." << std::endl;callback();
}// 回调函数1
void callback1() {std::cout << "Callback 1 called." << std::endl;
}// 回调函数2
void callback2() {std::cout << "Callback 2 called." << std::endl;
}int main() {// 使用 function 作为回调函数的容器function<void()> callbackFunc1 = callback1;function<void()> callbackFunc2 = callback2;// 执行异步操作,传递回调函数performAsyncOperation(callbackFunc1);// 执行异步操作,传递另一个回调函数performAsyncOperation(callbackFunc2);return 0;
}

在这个例子中,CallbackFunction 是一个 std::function 类型,用于表示无返回值且无参数的回调函数。performAsyncOperation 函数模拟了一个异步操作,完成后调用传递的回调函数。在 main 函数中,创建了两个不同的回调函数,然后分别传递给 performAsyncOperation 函数。

绑定器

std::bind用来将可调用对象与其参数一起进行绑定。绑定后的结果可以使用std::function进行保存,并延迟调用到任何我们需要的时候。通俗来讲,它主要有两大作用:

  1. 将可调用对象与其参数一起绑定成一个仿函数。
  2. 将多元(参数个数为n,n>1)可调用对象转换为一元或者(n-1)元可调用对象,即只绑定部分参数。

绑定器函数使用语法格式如下:

// 绑定非类成员函数/变量
auto f = std::bind(可调用对象地址, 绑定的参数/占位符);
// 绑定类成员函/变量
auto f = std::bind(类函数/成员地址, 类实例对象地址, 绑定的参数/占位符);

先来看两个简单例子:

#include <functional>
#include <iostream>void functionToBind(int a, int b) {std::cout << "Sum: " << a + b << std::endl;
}int main() {// 使用 std::bind 绑定函数和参数auto boundFunction = std::bind(functionToBind, 10, std::placeholders::_1);// 调用绑定的函数boundFunction(20);  // 输出 "Sum: 30"return 0;
}

在这个例子中,std::bind 绑定了 functionToBind 函数,并将第一个参数绑定为 10,第二个参数使用 std::placeholders::_1 占位符,表示稍后提供的参数。然后,通过调用 boundFunction(20),实际提供了一个参数 20,而 std::placeholders::_1 被替换为 20,最终调用了 functionToBind(10, 20)

#include <functional>
#include <iostream>class MyClass {
public:void memberFunction(int a, int b) {std::cout << "Sum: " << a + b << std::endl;}
};int main() {MyClass obj;// 使用 std::bind 绑定成员函数和对象auto boundMemberFunction = std::bind(&MyClass::memberFunction, &obj, 10, std::placeholders::_1);// 调用绑定的成员函数boundMemberFunction(20);  // 输出 "Sum: 30"return 0;
}

这个例子演示了如何使用 std::bind 绑定类的成员函数。注意,需要提供对象的地址作为第一个参数 , &obj 为第二个参数。后续的参数和占位符的使用方式与前面的例子类似。

在上面的程序中,使用了std::bind绑定器,在函数外部通过绑定不同的函数,控制了最后执行的结果。std::bind绑定器返回的是一个仿函数类型,得到的返回值可以直接赋值给一个std::function,在使用的时候我们并不需要关心绑定器的返回值类型,使用auto进行自动类型推导就可以了。

placeholders::_1是一个占位符,代表这个位置将在函数调用时被传入的第一个参数所替代。同样还有其他的占位符placeholders::_2、placeholders::_3、placeholders::_4、placeholders::_5等……

有了占位符的概念之后,使得std::bind的使用变得非常灵活:

#include <iostream>
#include <functional>
using namespace std;void output(int x, int y)
{cout << x << " " << y << endl;
}int main(void)
{// 使用绑定器绑定可调用对象和参数, 并调用得到的仿函数bind(output, 1, 2)();bind(output, placeholders::_1, 2)(10);bind(output, 2, placeholders::_1)(10);// error, 调用时没有第二个参数// bind(output, 2, placeholders::_2)(10);// 调用时第一个参数10被吞掉了,没有被使用bind(output, 2, placeholders::_2)(10, 20);function<void(int, int)> func1 = bind(output, placeholders::_1, placeholders::_2);auto func2 = bind(output, placeholders::_2, placeholders::_1);func1(10, 20);func2(10, 20);return 0;
}

示例代码执行的结果:

1  2		// bind(output, 1, 2)();
10 2		// bind(output, placeholders::_1, 2)(10);
2 10		// bind(output, 2, placeholders::_1)(10);
2 20		// bind(output, 2, placeholders::_2)(10, 20);
10 20		// bind(output, placeholders::_1, placeholders::_2)(10, 20);
20 10		// bind(output, placeholders::_2, placeholders::_1)(10, 20);

通过测试可以看到,std::bind可以直接绑定函数的所有参数,也可以仅绑定部分参数。在绑定部分参数的时候,通过使用std::placeholders来决定空位参数将会属于调用发生时的第几个参数。

可调用对象包装器std::function是不能实现对类成员函数指针或者类成员指针的包装的,但是通过绑定器std::bind的配合之后,就可以完美的解决这个问题了,再来看一个例子,然后再解释里边的细节:

#include <iostream>
#include <functional>
using namespace std;class Test
{
public:void output(int x, int y){cout << "x: " << x << ", y: " << y << endl;}int m_number = 100;
};int main(void)
{Test t;// 绑定类成员函数function<void(int, int)> f1 = bind(&Test::output, &t, placeholders::_1, placeholders::_2);// 绑定类成员变量(公共)function<int&(void)> f2 = bind(&Test::m_number, &t);// 调用f1(520, 1314);f2() = 2333;cout << "t.m_number: " << t.m_number << endl;return 0;
}

示例代码输出的结果:

x: 520, y: 1314
t.m_number: 2333

在用绑定器绑定类成员函数或者成员变量的时候需要将它们所属的实例对象一并传递到绑定器函数内部。f1的类型是function<void(int, int)>,通过使用std::bind将Test的成员函数output的地址和对象t绑定,并转化为一个仿函数并存储到对象f1中。

使用绑定器绑定的类成员变量m_number得到的仿函数被存储到了类型为function<int&(void)>的包装器对象f2中,并且可以在需要的时候修改这个成员。其中int是绑定的类成员的类型,并且允许修改绑定的变量,因此需要指定为变量的引用,由于没有参数因此参数列表指定为void。

示例程序中是使用function包装器保存了bind返回的仿函数,如果不知道包装器的模板类型如何指定,可以直接使用auto进行类型的自动推导,这样使用起来会更容易一些。

http://www.15wanjia.com/news/25597.html

相关文章:

  • 凯里做网站网站模板购买
  • 常州天宁区做网站公司网站优化公司排名
  • 重庆网站制作珠海公司做网站怎么赚钱
  • 做网站需要准备哪些西地那非
  • 自助建站最好的平台企业查询系统官网天眼查
  • 做木材生意的外贸网站百度下载安装2021最新版
  • 信息类网站有哪些ios微信上的pdf乱码
  • 做任务的电脑网站北京seo优化哪家公司好
  • 网站用什么字体做正文公司广告推广方案
  • 网站qq联系怎么做网络推广项目计划书
  • 第三方做公司网站企业如何进行品牌推广
  • 妙趣网 通辽网站建设google chrome网页版
  • 涿州做网站的公司seo网络推广技术员招聘
  • 装修的网站都有哪些淘宝seo搜索优化工具
  • 正规的培训行业网站制作seo方法图片
  • 手机版企页网站案例百度一下官方网页
  • logo网站在线制作网页设计图
  • 建筑方案的网站百度推广手机版
  • 建设网站教程2016怎么免费注册域名
  • 网站建设类行业资讯百度一下你就知道百度首页
  • 网站建设行业新闻培训心得体会万能模板
  • 做网站优惠泰安做百度推广的公司
  • wordpress怎么复制别人的西安seo教程
  • 房子装修找哪家好网站seo关键词排名优化
  • 山西电力建设三公司网站如何快速推广网上国网
  • 嘉兴网站排名公司广告推广媒体
  • 网站建设SEO优化哪家好关键词代发排名
  • 网站开发哪种语言sem培训班
  • 网站开发与维护的工作内容烟台百度推广公司
  • wordpress 后台风格主题厦门网站seo哪家好