美文网首页
C++函数使用与调用

C++函数使用与调用

作者: XGLey | 来源:发表于2017-10-14 12:11 被阅读0次

简介

本文主要介绍函数的定义与调用方法,函数配匹及实参与形参不在介绍之内。

一个函数需要有三个基本要素:函数名、参数和返回值。
但有一种特殊函数没有函数名,我们把它称为匿名函数。

函数基础

函数需要在定义或声明之后才能调用,否则会报出“未定义”错误。

auto add(const int x, const int y) -> int {
    return x + y;
}

int main(int, char **) {
    add(1, 2);
    return 0;
}

同样地,我们也可以先声明存在该函数,在以后实现它。

auto add(const int x, const int y) -> int;

int main(int, char **) {
    add(1, 2);
    return 0;
}

auto add(const int x, const int y) -> int {
    return x + y;
}

函数指针

定义

指针除了可以指向变量,它还可以指向一个函数。和其它指针一样,函数指针指向某种特定类型。函数的类型由它的返回类型和形参类型共同决定,与函数名无关。

以上面已定义好的add函数为例,声明指向add的指针,只需要用指针替换函数名即可:

int (*f) (const int x, const y);
f = add;

// 或者
int (*f) (const int x, const y) = add;

我们去观察它的声明,(*f)显然是个指针,右侧是它的形参例表,说明它指向一个函数,左侧说明是它的返回类型。

(*f)左右两侧的括号必不可少。

调用

我们拥有了函数指针之后,我们就可以像普通函数那样去调用它。

cout << f(1, 2) << endl;
// output: 3

由于f是个指针,所以它同样可以指向符合它类型的其它函数,只要形参列表和返回值一致。

auto add(const int x, const int y) -> int {
    return x + y;
}

int (*f) (const int x, const int y);
f = add;

cout << f(1, 2) << endl;
// output: 3

f = minus;
cout << f(1, 2) << endl;
// output: -1

那么我们可以把函数指针像普通指针一样,可以通过形参传递到另一个函数中呢?
当然是可以的。我们可以扩展add,实现CPS风格的add_cps

auto add_cps(const int x, const int y, int k (int)) -> int {
    auto a = add(x, y);
    return k(a);
}

int (*f) (int) = inc;
cout << add_cps(1, 2, f) << endl;

k即后续计算的函数指针,它跟int (*k) (int)的写法等价。

函数对象

定义

C++11之后,STL中提供<funtional>头部,这里可以处理很多函数对象。
我们可以利用std::function达到函数指针同样的效果。

std::function<int(int, int)> f = add;
cout << f(1, 2) << endl;

我们把指针f转变成了函数对象(funtion objects[1]),我们观察一下f的类型,std::function说明它是一个函数对象,<int(...)>中的int是函数的返回值,括号内是函数的形参列表,与函数指针对比,它们表达的信息相差无几。

偏函数

还记得刚才使用到的inc函数吗?它可以算是add(1)的偏函数了,我们可以利用std::bindadd函数特例化。

std::function<int(int)> inc = std::bind(add, 1, std::placeholders::_1);

cout << inc(1) << endl;
// output: 2

std::placeholders::_1是占位符,表明第一个参数会在这个位置被填充,同样还有_2及其它占位符。

传递函数对象

同理,函数对象也是能当作形参的,我们把原先的add_cps参形列表中的函数指针改成一个函数对象。

auto add_cps(const int x, const int y, std::function<int(int)> k) -> int {
    auto a = add(x, y);
    return k(a);
}

cout << add_cps(1, 2, inc) << endl;
// output: 4

改造之后,我们达到了与函数指针同样的效果。

高阶函数

我们可以传递函数了,那我们也可以实现更加高阶的函数,例如Haskell中的mapfilter等。

auto map(std::function<int(int)> f, const vector<int> &in) -> vector<int> {
    vector<int> v;
    for (const auto &i : in) {
        v.push_back(f(i));
    }

    return v;
}

auto filter(std::function<bool(int)> f, const vector<int> &in) -> vector<int> {
    vector<int> v;
    for (const auto &i : in) {
        if (f(i)) {
            v.push_back(i);
        }
    }

    return v;
}

注意:map在C++中表示一种数据结构,这里只作演示。

lambda函数

lambda函数(或称匿名函数)提供了四种写法[2]
在一些简法的计算中,除了重新定义一个具名函数,例如addinc,我们也可以在某个地方临时使用一下新函数,这时就可以交给lambda来做了。

上面我们实现了map函数,我们想让每个数都(+ 1)map接受的是一个函数,这里我们就可以临时使用lambda了。

std::vector<int> v{1, 2, 3};
map([](auto i) { return i + 1; }, v);
// 2 3 4

[](auto i) { return i + 1; }就是一条lambda函数,我们也可以把匿名函数赋值到std::function,让它重新变成一个函数对象。

std::function<int(int)> inc = [](auto i) {
    return i + 1;
};

showVec(map(inc, v));

有了lambda和函数对象,不必再像往常那样在外部定义只使用了一次的函数;在可读上面,我觉得lambda与function结合在一起可能会比较直观些。


  1. http://en.cppreference.com/w/cpp/utility/functional

  2. http://en.cppreference.com/w/cpp/language/lambda

相关文章

  • Python:重载构造方法

    对于使用过C++的人来说,构造函数与析构函数不会陌生。构造函数在对象创建时被调用,析构函数在对象被销毁时被调用。而...

  • C++函数使用与调用

    简介 本文主要介绍函数的定义与调用方法,函数配匹及实参与形参不在介绍之内。 一个函数需要有三个基本要素:函数名、参...

  • Python调用C++函数(SWIG,VS2013使用numpy

    最近尝试使用Python调用C++函数,发现网上都是一些简单的例子,涉及到Python Numpy数组与C++数组...

  • C&C++——C函数与C++函数相互调用问题

    【转载】C&C++——C函数与C++函数相互调用问题 C C++相互调用 在项目中融合C和C++有时是不可避免的,...

  • DLL调用

    使用VS2012生成DLL文件(1)在C++中调用DLL中的函数(2)在C++中调用DLL中的函数(3)在VS20...

  • extern "C"

    extern "C"主要用在c++调用c编写的函数或者相关代码时使用,因为c和c++的函数、变量结构类似,但是编译...

  • lua调用c++中的函数(使用LuaBridge)

    前面一节简述描写了如何在c++中调用lua函数,这节简述描写如何在lua中调用c++中的函数,还是使用前一节的工程...

  • Kotlin反射(4)调用构造函数

      通过反射调用构造函数与调用普通函数类似。通过反射调用构造函数也是使用 KFunction 实例,KFuncti...

  • 「转」C++ 和 JS 交互

    本章主要来讲讲如何通过 V8 来实现 JS 调用 C++。JS 调用 C++,分为 JS 调用 C++ 函数(全局...

  • C++子线程调用Java方法

    1. C++ 全局调用Java方法 之前讨论过,如何C++主线程中调用 Java 函数C++主线程调用Java方法...

网友评论

      本文标题:C++函数使用与调用

      本文链接:https://www.haomeiwen.com/subject/aoyxuxtx.html