在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
Ref: 【c++】可调用对象(Callable Objects) Five kinds of callable objects:
函数、函数指针1-2. Functions and Pointers to functions普通函数bool range5to10(int val) // <-- bool (*p_func)(int) 改为函数指针是一个道理
仿函数模板de仿函数更高逼格的template,至少能在类型上更加灵活一些。 template <class T, T lb, T ub>
auto presult = find_if(vec.begin(), vec.end(), range<int, 5, 10>{});
3. Object of class对象de仿函数class range {
public:
range(int l, int u): lb(l), ub(u) { // <-- 这里的构建函数的使用体现了其优势:初始化能多做些事情
}
bool operator() (int val) {
return (lb <=val && val <=ub);
}
private:
int lb, ub;
};
以及补充的三个例子。 struct MyPlus{ int operator() (const int &a , const int &b) const { return a + b; } }; int main() { MyPlus a; cout << MyPlus()(1,2) << endl; // 1、通过产生临时对象 调用重载运算符 cout << a.operator()(1,2) << endl; // 2、通过对象 显示调用重载运算符 cout << a(1,2) << endl; // 3、通过对象 隐示地调用重载运算符 return 0; }
std::function4. Bind占位符一个变量的占位符, 用于函数绑定时使用。 void f(int a, int b, int c)
{
cout << a << " " << b << " " << c << endl;
}
auto g1 = bind(f, placeholders::_1, placeholders::_2, 100);
能绑定什么Ref: C++11----std::bind/std::placeholder std::bind 是用来绑定函数调用的参数的,解决的需求 是: 我们有时候可能不会一次性获得调用某个函数的全部参数,通过这个函数,我们可以将部分调用参数提前绑定到函数身上成为一个新的对象,然后在参数齐全后,再完成调用。 #include <functional> #include <iostream> 提示:注意 auto 关键字的妙用。有时候我们可能不太熟悉一个函数的返回值类型,但是我们却可以通过 auto 的使用来规避这一问题的出现。 其中:绑定参数技术多用于设计模式中的适配器模式
参数绑定规则<示范一> fun1说明:占位符->第一个参数和函数第一个参数匹配(int),第二个参数和第二个参数匹配(char),第三个参数和第三个参数匹配。 fun2说明:占位符->第二个参数和函数第一个参数匹配(int),第三个参数和第二个参数匹配(char),第一个参数和第三个参数匹配。 fun3说明:占位符->第一个参数和函数第一个参数匹配(int),第二个参数和第二个参数匹配(char),第三个参数默认为98.77 #include <functional> #include <iostream> int TestFunc(int a, char c, float f) { std::cout << a << std::endl; std::cout << c << std::endl; std::cout << f << std::endl; return a; } int main(void) { auto fun1 = std::bind(TestFunc, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3); auto fun2 = std::bind(TestFunc, std::placeholders::_2, std::placeholders::_3, std::placeholders::_1); auto fun3 = std::bind(TestFunc, std::placeholders::_1, std::placeholders::_2, 98.77); fun1(30, 'C',100.1); fun2(100.1, 30, 'C'); fun3(30,'C'); return 0; }
<示范二> 这里placeholders的位置发生变化,看似对结果没有影响。 #include <functional> #include <iostream> #include <vector> #include <algorithm> using namespace std; class range { public: bool operator() (int lb, int ub, int val) { cout << "lb = " << lb << endl; cout << "ub = " << ub << endl; cout << "val = " << val << endl; return (lb <= val && val <= ub); } }; int main() { vector<int> vec = {1,2,3,4,5,6,7,8,9,10}; auto presult = find_if(vec.begin(), vec.end(), std::bind(range{}, 5, 10, std::placeholders::_1));
std::function初步认识,到底是个啥? std::function 在C++11后加入标准,可以用它来描述C++中所有可调用实体,它是 #include <functional>
比 “函数指针” 更强大? std::function 强大的地方在于,它能够 兼容所有具有相同参数类型的函数实体。 相比较于函数指针,std::function能兼容带捕获的
能力展示,遛一遛? 可以承接各种类型的函数,只要参数一致。 #include <iostream> #include <functional> // std::function std::function<int(int, int)> SumFunction; // 普通函数 int func_sum(int a, int b) { return a + b; } // 类(成员、静态)函数 class Calcu { public: int base = 20; // 类的成员方法,参数包含this指针 int class_func_sum(const int a, const int b) const { return this->base + a + b; }; // 类的静态成员方法,不包含this指针 static int class_static_func_sum(const int a, const int b) { return a + b; }; }; // 仿函数 class ImitateAdd { public: int operator() (const int a, const int b) const { return a + b; }; }; // lambda函数 auto lambda_func_sum = [](int a, int b) -> int { return a + b; }; // 函数指针 int (*func_pointer)(int, int); int main(void) { int x = 2; int y = 5; // 普通函数 SumFunction = func_sum; int sum = SumFunction(x, y); std::cout << "func_sum:" << sum << std::endl; // 类成员函数 Calcu obj; SumFunction = std::bind(&Calcu::class_func_sum, obj, std::placeholders::_1, std::placeholders::_2); // 绑定this对象 sum = SumFunction(x, y); std::cout << "Calcu::class_func_sum:" << sum << std::endl; // 类静态函数 SumFunction = Calcu::class_static_func_sum; sum = SumFunction(x, y); std::cout << "Calcu::class_static_func_sum:" << sum << std::endl; // lambda函数 SumFunction = lambda_func_sum; sum = SumFunction(x, y); std::cout << "lambda_func_sum:" << sum << std::endl; // 带捕获的lambda函数 int base = 10; auto lambda_func_with_capture_sum = [&base](int x, int y)->int { return x + y + base; }; SumFunction = lambda_func_with_capture_sum; sum = SumFunction(x, y); std::cout << "lambda_func_with_capture_sum:" << sum << std::endl; // 仿函数 ImitateAdd imitate; SumFunction = imitate; sum = SumFunction(x, y); std::cout << "imitate func:" << sum << std::endl; // 函数指针 func_pointer = func_sum; SumFunction = func_pointer; sum = SumFunction(x, y); std::cout << "function pointer:" << sum << std::endl; return 0; }
Lambda 函数5. Lambda Functions 初步认识“Lambda 表达式” (lambda expression)是一个匿名函数,Lambda表达式基于数学中的λ演算得名,直接对应于其中的lambda抽象(lambda abstraction),是一个匿名函数,即没有函数名的函数。 Lambda表达式可以表示闭包(注意和数学传统意义上的不同)。
返回值由于Lambda的类型是唯一的,不能通过类型名来显式声明对应的对象,但可以利用auto关键字和类型推导: auto f=[](int a,int b){return a>b;};
或者,返回值类型转换。 std::cout << [](float f) { return std::abs(f); } (-3.5); std::cout << [](float f) -> int { return std::abs(f); } (-3.5); 这个语句与前面的不同之处在于,lambda 表达式的返回时不是 float 而是 int。 第一个返回3.5;第二个返回3。
Return Type for Lambdas
参数基本定义 [] // 不捕获任何外部变量 [=] // 以值的形式捕获所有外部变量 [&] // 以引用形式捕获所有外部变量
捕获外部变量 float f0 = 1.0; std::cout << [=](float f) { return f0 + std::abs(f); } (-3.5); 传值:其输出值是 4.5 --------------------------------------------------------------------------------- float f0 = 1.0; std::cout << [&](float f) { return f0 += std::abs(f); } (-3.5); std::cout << '\n' << f0 << '\n'; 传引用:输出值是 4.5 和 4.5 --------------------------------------------------------------------------------- float f0 = 1.0; std::cout << [=](float f) mutable { return f0 += std::abs(f); } (-3.5); std::cout << '\n' << f0 << '\n'; 如果以传值的形式捕获外部变量,那么,lambda 体不允许修改外部变量。 你会觉得输出值是什么呢?答案是,4.5 和 1.0。 --------------------------------------------------------------------------------- float f0 = 1.0f; float f1 = 10.0f; std::cout << [=, &f0](float a) { return f0 += f1 + std::abs(a); } (-3.5); std::cout << '\n' << f0 << '\n'; 混合机制:这个例子的输出是 14.5 和 14.5。
不捕获外部变量 ** 捕获 **
End. |
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论