函数引用操作符

struct absInt
{
int operator()(int val) const
{
cout<<val<<"<->!!!"<<endl;
return val<0 ? -val : val;
}
};
void fun1()
{
int i=-42;
absInt absObj;
int ui=absObj(i);
}

Function-Object Classes with State

函数对象类的状态

class PrintString
{
public:
PrintString(ostream &o=cout, char c=' '):os(o), sep(c) {} //构造函数
void operator()(const string &s) const {os<<">>>>-----<<<<"<<s<<sep<<"yeah!"<<endl;} //函数操纵符
void operator()(const int i, const string &s1, const string &s2) const
{
if(i)
{
os<<"3 个參数 cutter_point-"<<s1<<endl;
}
else
{
os<<"3 个參数 cutter_point-"<<s2<<endl;
}
} private:
ostream &os; //输出流
char sep;
}; void fun2()
{
string s="cutter_point";
PrintString printer; //默认构造函数
printer(s); //调用操作符函数,输出:>>>>-----<<<<cutter_point yeah!
PrintString errors(cerr, '\n'); //上面yeah!前面变成换行
errors(s); vector<string> vs;
for(size_t i=0 ; i != 7 ; ++i)
{
stringstream ss;
ss<<i<<"-cutter_point";
vs.push_back(ss.str());
}
for_each(vs.begin(), vs.end(), PrintString(cerr, '\n')); PrintString three;
three(1, "我就是这么屌!", "没有,也就一般般啦!");
}

14.8.1. Lambdas Are Function Objects

void fun3()
{
vector<string> words;
for(size_t i=0 ; i != 7 ; ++i)
{
stringstream ss;
ss<<i<<"-cutter_point";
words.push_back(ss.str());
}
stable_sort(words.begin(), words.end(), [](const string &a, const string &b){return a.size()<b.size();});
for_each(words.begin(), words.end(), PrintString(cout, '3'));
} class ShorterString
{
public:
bool operator()(const string &s1, const string &s2) const
{return s1.size()<s2.size(); }
}; void fun4()
{
vector<string> words;
for(size_t i=8 ; i != -1 ; --i)
{
stringstream ss;
ss<<i<<"-cutter_point";
words.push_back(ss.str());
}
words.push_back("test排序"); stable_sort(words.begin(), words.end(), ShorterString());
for(vector<string>::iterator it=words.begin() ; it != words.end() ; ++it)
cout<<*it<<"\t";
}

Classes Representing Lambdas with Captures

void fun5()
{
vector<string> words;
vector<string>::size_type sz=5;
for(size_t i=8 ; i != -1 ; --i)
{
stringstream ss;
ss<<i<<"-cutter_point";
words.push_back(ss.str());
}
words.push_back("test排序"); //得到一个指向第一个s.size()>sz的元素
auto wc=find_if(words.begin(), words.end(), [sz](const string &a){return a.size() >= sz;});
for(vector<string>::iterator it=words.begin() ; it != words.end() ; ++it)
cout<<*it<<"\t";
if(wc != words.end())
{
cout<<"wc:"<<*wc<<endl;
} } class SizeComp
{
public:
SizeComp(size_t n):sz(n) {} //构造函数
bool operator()(const string &s) const {return s.size()>=sz;}
private:
size_t sz;
}; void fun6()
{
vector<string> words;
vector<string>::size_type sz=6;
for(size_t i=8 ; i != -1 ; --i)
{
stringstream ss;
ss<<i<<"-cutter_point";
words.push_back(ss.str());
}
words.push_back("test排序"); //得到一个指向第一个s.size()>sz的元素
auto wc=find_if(words.begin(), words.end(), SizeComp(sz));
///这里为什么会引用operator()操作呢?? cout<<endl;
if(wc != words.end())
{
cout<<"wc:"<<*wc<<endl;
}
}

14.8.2. Library-Defined Function Objects


void fun7()
{
plus<int> intAdd; //这个是能够加两个int型数字
negate<int> intNegate; //求相反数
int sum=intAdd(10, 20); //结果30
cout<<sum<<endl;
sum=intNegate(intAdd(10, 20)); //结果-30
cout<<sum<<endl;
sum=intAdd(10, intNegate(10)); //结果0
cout<<sum<<endl;
}

Using a Library Function Object with the Algorithms
void fun8()
{
vector<string> svec={"i","like","china","so","much","I","can","just","do","it"};
//通过一个暂时的函数对象应用<操作对两个string
sort(svec.begin(), svec.end(), greater<string>());
//输出结果按字典位置排序,然后大写在后,递减排序
for_each(svec.begin(), svec.end(), [](string &s){cout<<s<<"\t";});
}

通过指针直接操作内存的地址,来改变排序

void fun9()
{
vector<string> svec={"i","like","china","so","much","I","can","just","do","it"};
vector<string*> nameTable;
for(vector<string>::iterator it=svec.begin() ; it != svec.end() ; ++it)
{
string* s=new string; //这里new string一定要加!!,为了给s分配空间
*s=*it;
nameTable.push_back(s);
} // sort(nameTable.begin(), nameTable.end(), [](string* a, string* b){return a<b;});
sort(nameTable.begin(), nameTable.end(), less<string*>());
//输出的是按内存位置来输出的
for(vector<string*>::iterator it=nameTable.begin() ; it != nameTable.end() ; ++it)
cout<<*(*it)<<"\t";
}

14.8.3. Callable Objects and function

可调用对象和函数


Different Types Can Have the Same Call Signature


int add(int i, int j) {return i+j;}
void fun10()
{
auto mod=[](int i, int j){return i%j;};
}
struct div2 //这里不要用div好像是和stdlib.h冲突了
{
int operator()(int denominator, int divisor){return denominator/divisor;}
}; //上面三个都是int(int, int)类型的

我们能够定义一个map,用string类型来关联对应的函数,用string作为标识

void fun11()
{
auto mod=[](int i, int j){return i%j;};
map<string, int(*)(int, int)> binops; //这是一个函数指针,返回一个int类型
//这里add是一个指向+运算的指针,div是不能这样加的,它不是指针
binops.insert({"+", add});
binops.insert({"%", mod});
// binops.insert({"/", div2});
}

库函数类型


void fun12()
{
function<int(int, int)> f1=add; //函数指针,这个是加法
function<int(int, int)> f2=div2(); //调用()操作符,这个是除法
function<int(int, int)> f3=[](int i, int j) {return i*j;}; //lambda返回乘法
cout<<f1(4,2)<<endl; //6
cout<<f2(4,2)<<endl; //2
cout<<f3(4,2)<<endl; //8
} void fun13()
{
auto mod=[](int i, int j){return i%j;};
map<string, function<int(int, int)>> binops=
{
{"+", add},{"-", std::minus<int>()},{"/", div2()},{"*", [](int i, int j){return i*j;}},
{"%", mod}
}; //这个map有五个元素,当我们索引这个map的时候,我们能够调用这五个函数类型 cout<<"+ <--->"<<binops["+"](10, 5)<<endl;
cout<<"- <--->"<<binops["-"](10, 5)<<endl;
cout<<"/ <--->"<<binops["/"](10, 5)<<endl;
cout<<"* <--->"<<binops["*"](10, 5)<<endl;
cout<<"% <--->"<<binops["%"](10, 5)<<endl;
}

Overloaded Functions and function

重载的函数和功能

void fun14()
{
map<string, function<int(int, int)>> binops;
int (*fp)(int, int)=add;
binops.insert({"+", fp}); //用函数指针来避免重载,或者同名函数的含糊不清
//含有一个非常好的办法就是使用lambda来消除歧义是非常好的
binops.insert({"+", [](int a, int b){return add(a,b);}}); }

在新的库函数类是不相关的类命名为

unary_function和binary_function是较早的版本号的一部分

标准库。这些类被更一般的结合使用函数代替


全代码!


/**
* 功能:函数引用操作符
* 时间:2014年7月18日16:11:45
* 作者:cutter_point
*/ #include<iostream>
#include<cstring>
#include<vector>
#include<algorithm>
#include<sstream>
#include<string>
#include<map>
#include<functional> using namespace std; struct absInt
{
int operator()(int val) const
{
cout<<val<<"<->!!!"<<endl;
return val<0 ? -val : val;
}
}; void fun1()
{
int i=-42;
absInt absObj;
int ui=absObj(i);
} /**
Function-Object Classes with State
函数对象类的状态
*/
class PrintString
{
public:
PrintString(ostream &o=cout, char c=' '):os(o), sep(c) {} //构造函数
void operator()(const string &s) const {os<<">>>>-----<<<<"<<s<<sep<<"yeah!"<<endl;} //函数操纵符
void operator()(const int i, const string &s1, const string &s2) const
{
if(i)
{
os<<"3 个參数 cutter_point-"<<s1<<endl;
}
else
{
os<<"3 个參数 cutter_point-"<<s2<<endl;
}
} private:
ostream &os; //输出流
char sep;
}; void fun2()
{
string s="cutter_point";
PrintString printer; //默认构造函数
printer(s); //调用操作符函数,输出:>>>>-----<<<<cutter_point yeah!
PrintString errors(cerr, '\n'); //上面yeah!前面变成换行
errors(s); vector<string> vs;
for(size_t i=0 ; i != 7 ; ++i)
{
stringstream ss;
ss<<i<<"-cutter_point";
vs.push_back(ss.str());
}
for_each(vs.begin(), vs.end(), PrintString(cerr, '\n')); PrintString three;
three(1, "我就是这么屌!", "没有,也就一般般啦!");
} /**
14.8.1. Lambdas Are Function Objects
*/
void fun3()
{
vector<string> words;
for(size_t i=0 ; i != 7 ; ++i)
{
stringstream ss;
ss<<i<<"-cutter_point";
words.push_back(ss.str());
}
stable_sort(words.begin(), words.end(), [](const string &a, const string &b){return a.size()<b.size();});
for_each(words.begin(), words.end(), PrintString(cout, '3'));
} class ShorterString
{
public:
bool operator()(const string &s1, const string &s2) const
{return s1.size()<s2.size(); }
}; void fun4()
{
vector<string> words;
for(size_t i=8 ; i != -1 ; --i)
{
stringstream ss;
ss<<i<<"-cutter_point";
words.push_back(ss.str());
}
words.push_back("test排序"); stable_sort(words.begin(), words.end(), ShorterString());
for(vector<string>::iterator it=words.begin() ; it != words.end() ; ++it)
cout<<*it<<"\t";
} /**
Classes Representing Lambdas with Captures
*/
void fun5()
{
vector<string> words;
vector<string>::size_type sz=5;
for(size_t i=8 ; i != -1 ; --i)
{
stringstream ss;
ss<<i<<"-cutter_point";
words.push_back(ss.str());
}
words.push_back("test排序"); //得到一个指向第一个s.size()>sz的元素
auto wc=find_if(words.begin(), words.end(), [sz](const string &a){return a.size() >= sz;});
for(vector<string>::iterator it=words.begin() ; it != words.end() ; ++it)
cout<<*it<<"\t";
if(wc != words.end())
{
cout<<"wc:"<<*wc<<endl;
} } class SizeComp
{
public:
SizeComp(size_t n):sz(n) {} //构造函数
bool operator()(const string &s) const {return s.size()>=sz;}
private:
size_t sz;
}; void fun6()
{
vector<string> words;
vector<string>::size_type sz=6;
for(size_t i=8 ; i != -1 ; --i)
{
stringstream ss;
ss<<i<<"-cutter_point";
words.push_back(ss.str());
}
words.push_back("test排序"); //得到一个指向第一个s.size()>sz的元素
auto wc=find_if(words.begin(), words.end(), SizeComp(sz));
///这里为什么会引用operator()操作呢?? cout<<endl;
if(wc != words.end())
{
cout<<"wc:"<<*wc<<endl;
}
} /**************************************
14.8.2. Library-Defined Function Objects
**************************************/
void fun7()
{
plus<int> intAdd; //这个是能够加两个int型数字
negate<int> intNegate; //求相反数
int sum=intAdd(10, 20); //结果30
cout<<sum<<endl;
sum=intNegate(intAdd(10, 20)); //结果-30
cout<<sum<<endl;
sum=intAdd(10, intNegate(10)); //结果0
cout<<sum<<endl;
} /**************************************
Using a Library Function Object with the Algorithms
**************************************/
void fun8()
{
vector<string> svec={"i","like","china","so","much","I","can","just","do","it"};
//通过一个暂时的函数对象应用<操作对两个string
sort(svec.begin(), svec.end(), greater<string>());
//输出结果按字典位置排序,然后大写在后,递减排序
for_each(svec.begin(), svec.end(), [](string &s){cout<<s<<"\t";});
} //通过指针直接操作内存的地址,来改变排序
void fun9()
{
vector<string> svec={"i","like","china","so","much","I","can","just","do","it"};
vector<string*> nameTable;
for(vector<string>::iterator it=svec.begin() ; it != svec.end() ; ++it)
{
string* s=new string; //这里new string一定要加!!,为了给s分配空间
*s=*it;
nameTable.push_back(s);
} // sort(nameTable.begin(), nameTable.end(), [](string* a, string* b){return a<b;});
sort(nameTable.begin(), nameTable.end(), less<string*>());
//输出的是按内存位置来输出的
for(vector<string*>::iterator it=nameTable.begin() ; it != nameTable.end() ; ++it)
cout<<*(*it)<<"\t";
} /**************************************
14.8.3. Callable Objects and function
可调用对象和函数
**************************************/ /**
Different Types Can Have the Same Call Signature
*/
int add(int i, int j) {return i+j;}
void fun10()
{
auto mod=[](int i, int j){return i%j;};
}
struct div2 //这里不要用div好像是和stdlib.h冲突了
{
int operator()(int denominator, int divisor){return denominator/divisor;}
}; //上面三个都是int(int, int)类型的 /*
我们能够定义一个map,用string类型来关联对应的函数,用string作为标识
*/
void fun11()
{
auto mod=[](int i, int j){return i%j;};
map<string, int(*)(int, int)> binops; //这是一个函数指针,返回一个int类型
//这里add是一个指向+运算的指针,div是不能这样加的,它不是指针
binops.insert({"+", add});
binops.insert({"%", mod});
// binops.insert({"/", div2});
} /**
库函数类型
*/
void fun12()
{
function<int(int, int)> f1=add; //函数指针,这个是加法
function<int(int, int)> f2=div2(); //调用()操作符,这个是除法
function<int(int, int)> f3=[](int i, int j) {return i*j;}; //lambda返回乘法
cout<<f1(4,2)<<endl; //6
cout<<f2(4,2)<<endl; //2
cout<<f3(4,2)<<endl; //8
} void fun13()
{
auto mod=[](int i, int j){return i%j;};
map<string, function<int(int, int)>> binops=
{
{"+", add},{"-", std::minus<int>()},{"/", div2()},{"*", [](int i, int j){return i*j;}},
{"%", mod}
}; //这个map有五个元素,当我们索引这个map的时候,我们能够调用这五个函数类型 cout<<"+ <--->"<<binops["+"](10, 5)<<endl;
cout<<"- <--->"<<binops["-"](10, 5)<<endl;
cout<<"/ <--->"<<binops["/"](10, 5)<<endl;
cout<<"* <--->"<<binops["*"](10, 5)<<endl;
cout<<"% <--->"<<binops["%"](10, 5)<<endl;
} /**
Overloaded Functions and function
重载的函数和功能
*/
void fun14()
{
map<string, function<int(int, int)>> binops;
int (*fp)(int, int)=add;
binops.insert({"+", fp}); //用函数指针来避免重载,或者同名函数的含糊不清
//含有一个非常好的办法就是使用lambda来消除歧义是非常好的
binops.insert({"+", [](int a, int b){return add(a,b);}}); } /*
在新的库函数类是不相关的类命名为
unary_function和binary_function是较早的版本号的一部分
标准库。这些类被更一般的结合使用函数代替
*/ int main()
{
cout<<">>----------------fun1---------------------<<"<<endl;
fun1();
cout<<">>----------------fun2---------------------<<"<<endl;
fun2();
cout<<">>----------------fun3---------------------<<"<<endl;
fun3();
cout<<">>----------------fun4---------------------<<"<<endl;
fun4();
cout<<">>----------------fun5---------------------<<"<<endl;
fun5();
cout<<">>----------------fun6---------------------<<"<<endl;
fun6();
cout<<">>----------------fun7---------------------<<"<<endl;
fun7();
cout<<">>----------------fun8---------------------<<"<<endl;
fun8();
cout<<">>----------------fun9---------------------<<"<<endl;
fun9();
cout<<">>----------------fun12---------------------<<"<<endl;
fun12();
cout<<">>----------------fun13---------------------<<"<<endl;
fun13(); system("pause");
return 0;
}

PS:今天早上有点晚了,不行,以后每天早上坚持至少8点開始,7点起床!!!努力,我要学的东西还非常多,远远不够,时间如此紧迫,怎可徒费光阴!!!

【足迹C++primer】48、函数引用操作符的更多相关文章

  1. 《C++ Primer》之重载操作符与转换(下)

    转换与类类型 可用一个实参调用的非 explicit 构造函数定义一个隐式转换.当提供了实参类型的对象而需要一个类类型的对象时,编译器将使用该转换.这种构造函数定义了到类类型的转换.除了定义到类类型的 ...

  2. [转] PostgreSQL学习手册(函数和操作符)

    一.逻辑操作符: 常用的逻辑操作符有:AND.OR和NOT.其语义与其它编程语言中的逻辑操作符完全相同. 二.比较操作符: 下面是PostgreSQL中提供的比较操作符列表: 操作符 描述 < ...

  3. 《C++ Primer》之重载操作符与转换(中)

    赋值操作符 类赋值操作符接受类类型形参,通常,该形参是对类类型的 const 引用,但也可以是类类型或对类类型的非 const 引用.如果没有定义这个操作符,则编译器将合成它.类赋值操作符必须是类的成 ...

  4. C++ Primer 有感(重载操作符)

    1.用于内置类型的操作符,其含义不能改变.也不能为任何内置类型定义额外的新的操作符.(重载操作符必须具有至少一个类类型或枚举类型的操作数.这条规则强制重载操作符不能重新定义用于内置类型对象的操作符的含 ...

  5. scala快速学习笔记(一):变量函数,操作符,基本类型

    为了用spark,先学下scala. 参考教程:http://meetfp.com/zh/scala-basic doc查询:http://docs.scala-lang.org 其它资料:http: ...

  6. PostgreSQL学习手册(五) 函数和操作符

    PostgreSQL学习手册(五) 函数和操作符 一.逻辑操作符:    常用的逻辑操作符有:AND.OR和NOT.其语义与其它编程语言中的逻辑操作符完全相同. 二.比较操作符:    下面是Post ...

  7. C++基础 (4) 第四天 this指针 全局函数和成员函数 友元 操作符重载

    1static强化练习-仓库进货和出货 #define _CRT_SECURE_NO_WARNINGS #include <iostream> using namespace std; c ...

  8. Jmeter外部函数引用

    Jmeter外部函数引用 1.Beanshell引用Jmeter变量 添加用户自定义变量,输入变量名称和变量值,添加Debug sampler,用于输出初始变量值.

  9. PostgreSql字符串函数和操作符

    本节描述了用于检查和操作字符串数值的函数和操作符.在这个环境中的字符串包括所有 character, character varying, text 类型的值.除非另外说明,所有下面列出的函数都可以处 ...

随机推荐

  1. 命令行參数选项处理:getopt()及getopt_long()函数使用

         在执行某个程序的时候,我们通常使用命令行參数来进行配置其行为.命令行选项和參数控制 UNIX 程序,告知它们怎样动作. 当 gcc的程序启动代码调用我们的入口函数 main(int argc ...

  2. 【HDU】4888 Redraw Beautiful Drawings 网络流【推断解是否唯一】

    传送门:pid=4888">[HDU]4888 Redraw Beautiful Drawings 题目分析: 比赛的时候看出是个网络流,可是没有敲出来.各种反面样例推倒自己(究其原因 ...

  3. 成为JAVA软件开发工程师要学哪些东西

    2010-04-22 15:34 提问者采纳 Java EE(旧称j2ee)   第一阶段:Java基础,包括java语法,面向对象特征,常见API,集合框架: *第二阶段:java界面编程,包括AW ...

  4. OpenCV, color reduction method

    转载请注明出处!!!http://blog.csdn.net/zhonghuan1992 OpenCV, colorreduction method 目标: 这次学习的目标是回答以下的几个问题: 1 ...

  5. Web Worker在WebKit中的实现机制

    web worker 是执行在后台的 JavaScript,独立于其它脚本.不会影响页面的性能.这是HTML5的一个标准:实现上讲.浏览器为wokrer启动了新的线程,从而实现了异步操作的功能; 以下 ...

  6. C#中使用gRPC

    C#中使用gRPC 我的这几篇文章都是使用gRPC的example,不是直接编译example,而是新建一个项目,从添加依赖,编译example代码,执行example.这样做可以为我们创建自己的项目 ...

  7. mysql 触发器和存储过程组合使用,实现定时触发操作

    mysql可以实现定时触发功能,比如说定于某某时间mysql数据库做什么工作,或每隔多长时间做什么工作. 第二种情况应用还是比较广的,比如说我希望每天检查一下我的数据信息,超过一个月的无用信息清除以腾 ...

  8. 算法战斗:给定一个号码与通配符问号W,问号代表一个随机数字。 给定的整数,得到X,和W它具有相同的长度。 问:多少整数协议W的形式和的比率X大?

    如果说: 给定一个号码与通配符问号W,问号代表一个随机数字. 给定的整数,得到X,和W它具有相同的长度. 问:多少整数协议W的形式和的比率X大? 进格公式 数据的多组,两排各数据的,W,第二行是X.它 ...

  9. “AIR SDK 0.0: AIR SDK location “...\devsdks\AIRSDK\Win” does not exist.”问题解决~

    原文同步至:http://www.waylau.com/air-sdk-0-0-air-sdk-location-does-not-exist-address/ 导入AS3项目时提示“AIR SDK ...

  10. yum 简介及使用 安装、删除

    使用yum装软件很方便,这里简单介绍一下. Yum简介 Yum(全称为 Yellow dog Updater, Modified)是一个在Fedora和RedHat以及SUSE.CentOS中的She ...