C++⼊门教程(三⼗五):函数类型
⽬录
函数类型
函数实际上也是⼀个值,也就是说,函数可以⽤变量来保存,⽽这个变量的数据类型是std::function。std::function是⼀个类,它
在functional标准库中。
假设要保存函数int myabs(int num);,那么就需要使⽤数据类型std::fuction<int(int)>,即在std::function的<>⾥⾯填返回值(参数类型),完整的赋值语句是std::function<int(int)> myfunc = myabs;。当然也可以⽤auto来声明变量:auto myfunc = myabs;。
简短的⽰例:
int myabs(int num); // 声明函数
std::function<int(int)> myfunc = myabs; // ⽤变量myfunc保存myabs函数
myabs(-1024); // 函数的调⽤
myfunc(-2333); // 这时候myfunc也是函数,调⽤⽅法和上⾯myabs⼀样
以下讲解函数类型的⽤途,即为什么要⽤函数类型。先看⼏个问题。
写⼀个函数,函数声明是这样的:unsigned int count_gu(std::u32string text);;功能是⽤来统计指定字符串中有多少个古字;函数有⼀个参数text,就是需要被统计的字符串;返回类型是unsigned int,代表字符串中有多少个古字。
基础⽰例 1
#include <iostream> // std::cout std::endl
#include <string> // std::u32string
// 以下是统计函数的使⽤说明
// 功能: 统计指定字符串中有多少个古字
// 参数: 需要被统计的字符串
// 返回值: 字符串中古字的数量
unsigned int count_gu(std::u32string text);
int main(void)
{
// 统计字符串中⼀共有多少个古字
auto numofgu = count_gu(U"⼩古银⼩古银我是美美哒⼩古银");
std::cout << R"raw(字符串有多少个古字:)raw" << numofgu << std::endl;
return 0;
}
unsigned int count_gu(std::u32string text)
{
/
/ 遍历字符串中所有字符, 如果符合条件则统计
unsigned int count = 0; // ⽤来保存统计数量
for (auto ch : text)
{
if (ch == U'古')
{
++count;
}
}
// 返回统计数量
return count;
}
输出结果:
字符串有多少个古字:3
再写⼀个函数,函数声明是这样的:unsigned int count_guyin(std::u32string text);;功能是⽤来统计古字和银字在指定字符串中⼀共有多少个;函数有⼀个参数text,就是需要被统计的字符串;返回类型是unsigned int,代表字符串中⼀共有多少个古字和银字。
基础⽰例 2
#include <iostream> // std::cout std::endl
#include <string> // std::u32string
// 以下是统计函数的使⽤说明
// 功能: 统计指定字符串中⼀共有多少个古字和银字
// 参数: 需要被统计的字符串
// 返回值: 字符串中古字和银字的数量
unsigned int count_guyin(std::u32string text);
int main(void)
{
// 统计字符串中⼀共有多少个古字
auto numofguyin = count_guyin(U"⼩古银⼩古银我是美美哒⼩古银");
std::cout << R"raw(字符串有多少个古字和银字:)raw" << numofguyin << std::endl;
return 0;
}
unsigned int count_guyin(std::u32string text)
{
/
/ 遍历字符串中所有字符, 如果符合条件则统计
unsigned int count = 0; // ⽤来保存统计数量
for (auto ch : text)
{
if (ch == U'古' || ch == U'银')
{
++count;
}
}
// 返回统计数量
return count;
}
输出结果:
字符串有多少个古字和银字:6
基础讲解 2
可以看出两份代码中,unsigned int count_gu(std::u32string text);和unsigned int count_guyin(std::u32string text);的函数定义除了if的判断不同,其他部分是⼀模⼀样的。既然两个函数的功能都是统计,⽽定义基本都是⼀样,那么就要考虑把它们统⼀成⼀个函数。
之前是因为值不同,所以可以⽤变量来作为函数参数来保存不同的值;⽽现在是不同的语句,可以考虑将语句写在函数⾥。上⾯说明过,函数也是⼀个值,不同的函数是不同的值,既然是值就可以⽤变量来保存。那么就可以将判断语句放到函数⾥,然后通过形式参数传到统计函数⾥。这时候就要考虑,这个⽤来判断的函数怎样写,同样也要考虑参数的类型是什么。
这个判断函数是⽤来放判断条件的。之前说过,判断就是⼀个运算,⽽运算结果是bool,那么这个判断函数的返回值就是bool。⽽需要判断的就是⼀个字符,那么形式参数的类型就是char32_t。这样,我们⾃⼰定义函数名isgu⽤来判断字符是不是古字,定义函数名isguyin⽤来判断字符是不是古字或者
银字。这两个函数的函数声明如下:
bool isgu(char32_t ch);
bool isguyin(char32_t ch);
由于它们的返回值和参数类型都是⼀样的,那么它们都可以⽤类型std::function<bool(char32_t)>声明的变量来保存,例⼦如下:
std::function<bool(char32_t)> isgufunc = isgu;
std::function<bool(char32_t)> isguyinfunc = isguyin;
所以可以⽤数据类型std::function<bool(char32_t)>来作为统计函数的参数的数据类型。基础⽰例 3
那么将两个函数统⼀成⼀个函数就可以这样写:
#include <iostream> // std::cout std::endl
#include <functional> // std::function
#include <string> // std::u32string
// 以下是统计函数的使⽤说明
// 功能: 统计函数
// 参数: 需要被统计的字符串
// 参数: 统计函数需要的判断函数, 统计函数将会向判断函数传⼊每⼀个字符,
// 然后统计函数会根据判断函数的返回值进⾏统计, 如果判断函数返回
// true, 统计函数则会处理; 如果判断函数返回false, 统计函数则忽略
// 返回值: 统计判断函数返回true的数量
unsigned int count_if(std::u32string text, std::function<bool(char32_t)> pred);
// 判断指定的UTF-32字符是不是古字
// 参数: 需要判断的字符
// 返回值: 如果指定字符是古字则返回true; 反之返回false
bool isgu(char32_t ch);
// 判断指定的UTF-32字符是不是古字或者银字
// 参数: 需要判断的字符
// 返回值: 如果指定字符是古字或者银字则返回true; 反之返回false
bool isguyin(char32_t ch);
int main(void)
{
// 统计字符串中⼀共有多少个古字
auto numofgu = count_if(U"⼩古银⼩古银我是美美哒⼩古银", isgu);
// 统计字符串中⼀共有多少个古银这两个字
auto numofguyin = count_if(U"⼩古银⼩古银我是美美哒⼩古银", isguyin);
/
/ 输出
std::cout << R"raw(字符串有多少个古字:)raw" << numofgu << std::endl;
std::cout << R"raw(字符串有多少个古字和银字:)raw" << numofguyin << std::endl;
false是什么函数return 0;
}
unsigned int count_if(std::u32string text, std::function<bool(char32_t)> pred)
{
// 遍历字符串中所有字符, 如果符合条件则统计
unsigned int count = 0; // ⽤来保存统计数量
for (auto ch : text)
{
if (pred(ch))
{
++count;
}
}
// 返回统计数量
return count;
}
bool isgu(char32_t ch)
{
return ch == U'古';
}
bool isguyin(char32_t ch)
{
return ch == U'古' || ch == U'银';
}
输出结果:
字符串有多少个古字:3
字符串有多少个古字和银字:6
基础讲解 3
先从设计函数的思维去看:函数count_if()⽤来统计符合条件的字符数量。然⽽函数count_if()只负责统
计,它并不知道什么样的条件是符合的,他就把这个任务交给参数pred去负责,把每只字符都给pred()函数判断⼀下,只要pred()函数返回true,函数count_if()就认为是符合条件⽽去统计。那么函数count_if()就可以专⼼负责统计⽽不⽤理会细节。⽽参数pred就⾝负着判断是否符合条件的重任,它化⾝成为类型是std::function<bool(char32_t)>的函数,只为了完成判断每种不同条件的光荣使命。
再从调⽤函数的⾓度去玩:就是统计函数的使⽤说明。函数count_if()的第⼀个参数是需要被统计的字符串,⽽第⼆个参数是给函
数count_if()判断⽤的,应该由调⽤者来定义什么字符是需要被统计的。我们需要统计有多少个古字,还有需要统计⼀共有多少个古字
和银字,所以就写了两个判断函数isgu和isguyin,供统计函数判断使⽤。
补充知识(了解即可)
std::function从C++11开始加⼊。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论