typedef 与函数指针/函数对象/函数符

https://stackoverflow.com/questions/1666353/are-typedef-and-define-the-same-in-c

1.函数对象(c++primer plus P707)

在这里插入图片描述
下面这个解释很重要!
在这里插入图片描述

2.STL,Sort 函数对象,函数符相关

转自 http://www.cplusplus.com/reference/algorithm/sort/?kw=sort
在这里插入图片描述
这里注意最后两个例子,一个相当是使用了函数指针(或者说通过函数指针传递),一个是函数对象

// sort algorithm example
#include <iostream>     // std::cout
#include <algorithm>    // std::sort
#include <vector>       // std::vector

bool myfunction (int i,int j) { return (i<j); }

struct myclass {
  bool operator() (int i,int j) { return (i<j);}
} myobject;

int main () {
  int myints[] = {32,71,12,45,26,80,53,33};
  std::vector<int> myvector (myints, myints+8);               // 32 71 12 45 26 80 53 33

  // using default comparison (operator <):
  std::sort (myvector.begin(), myvector.begin()+4);           //(12 32 45 71)26 80 53 33

  // using function as comp
  std::sort (myvector.begin()+4, myvector.end(), myfunction); // 12 32 45 71(26 33 53 80)

  // using object as comp
  std::sort (myvector.begin(), myvector.end(), myobject);     //(12 26 32 33 45 53 71 80)

  // print out content:
  std::cout << "myvector contains:";
  for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';

  return 0;
}

3.函数指针

函数指针的声明一般都是 特定自定义 的名称,比如下面的p1是自定义的

const double* f2(const double [],int);
/*下面两种声明是一样的*/
const double* (*p1) (const double*,int );//声明了const double* (constdouble*, int)类型的函数指针p1
auto p2=f2;//非常好用的声明

可以使用函数指针来调用函数

//以下两种方式都可以调用函数
p2(3.4,1);// ok
(*p2)(3.4,1);//ok

使用typedef来进行简化

//将特定类型的函数typedef为func_ptr,然后可以声明对应的变量f1,可以把具体的函数赋值给f1
typedef void (*func_ptr)(int );
func_ptr f1;
f1=F_anotherFun;

把函数作为参数传入另一个函数(转自知乎)

https://zhuanlan.zhihu.com/p/37306637
例子1,这里的f相当于一个形式参数,是通过函数地址值的值传递,不过仍然可以调用

#include <iostream>
int add(int a, int b){
    return a+b;
}
int sub(int a, int b){
    return a-b;
}
void func(int e, int d, int(*f)(int a, int b)){ // 这里才是我想说的,
// 传入了一个int型,双参数,返回值为int的函数
    std::cout<<f(e,d)<<std::endl;
}
int main()
{
    func(2,3,add);
    func(2,3,sub);

    return 0;
}

例子2,用于排序

#include <iostream>
template <typename T>
bool ascending(T x, T y) {
    return x > y; 
}
template <typename T>
bool descending(T x, T y) {
    return x < y;
}
template<typename T>
void bubblesort(T *a, int n, bool(*cmpfunc)(T, T)){
    bool sorted = false;
    while(!sorted){
        sorted = true;
        for (int i=0; i<n-1; i++)
            if (cmpfunc(a[i], a[i+1])) {
                std::swap(a[i], a[i+1]);
                sorted = false;
            }
        n--;
    }
}

int main()
{
    int a[8] = {5,2,5,7,1,-3,99,56};
    int b[8] = {5,2,5,7,1,-3,99,56};

    bubblesort<int>(a, 8, ascending);

    for (auto e:a) std::cout << e << " ";
    std::cout << std::endl;

    bubblesort<int>(b, 8, descending);

    for (auto e:b) std::cout << e << " ";

    return 0;
}
// -3 1 2 5 5 7 56 99 
// 99 56 7 5 5 2 1 -3 [Finished in 0.4s]

总结

1.函数符号是可以以函数方式与()结合的任意对象。包括1.函数名、2.指向函数的指针、3.重载了()运算符的类对象(即定义了函数operator()()的类)
2.关于返回值为函数指针的理解可以看这篇文章
https://blog.csdn.net/lyn_00/article/details/83549655
3.关于函数对象
既然函数对象是一个具体的实体对象,那么它既可以单独使用,也可以像函数指针一样被当成参数传递给其他函数,并在其他函数中使用。另外,函数对象在带来便利的同时并不会影响程序的性能。它一般没有构造函数和析构函数,因此,在创建或销毁函数对象的过程中不会有额外的性能消耗。同时,“( )”操作符往往是一个内联函数,编译器能内联它的代码,从而避免了与函数调用相关的性能损失。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值