C++可调用对象

C++可调用对象

  对于一个对象或表达式,若果可以对其使用调用运算符,则称他为可调用的。
  函数调用对象:函数、函数指针、重载了调用运算符的类和lambda表达式。

一、函数

格式:
  return_type func_name(parameters…){function_body}
  auto func_name(parameters…)->return_type{function_body}

int add(const int &a, const int &b)
{
    return a + b;
}

auto sub(const int &a, const int &b)->int 
{
    return a - b;
}

int main(int argc, char** argv)
{
    std::cout << add(1,2) << std::endl;
    std::cout << sub(1,2) << std::endl;
    return 0;
}

二、函数指针

  格式:
    函数定义格式:return_type func_name(parameters…){function_body};
    函数指针格式(在函数明前加’*’):return_type (*func_name)(parameters…){function_body};

#include<iostream>

int add(const int &a, const int &b)
{
    return a + b;
}

typedef int (*fun)(const int &a, const int &b);

int main(int argc, char **argv)
{
    fun l_add = add;
    std::cout << l_add(1,2) << std::endl;
    int (*l_add2)(const int &a, const int &b) = add;
    std::cout << l_add2(3,4) << std::endl;
    return 0;
}

三、重载了调用运算符的类

  如果类定义了调用运算符,则该类的的对象成为函数对象。
  格式:
    return_type operator()(parameters…){function_body}

class absInt{
public:
    absInt(){};
    ~absInt(){};
public:
    int operator()(const int &a, const int &b)
    {
        return a + b;
    }
};
int main(int argc, char **argv)
{
    absInt myint;
    std::cout << myint(1,2) << std::endl;
    return 0;
}

四、lambda表达式

1)概念

  lambda表达式:一个可调用的代码单元,可理解为一个未命名的内联函数。
  lambda与函数类似,有返回值类型、参数列表和函数体;
  不同的是:
    lambda可定义在函数内部;
    lambda有一个捕获列表用来捕获所在函数体内的局部变量(通常为空);
    lambda必须使用尾置返回来指定返回值类型;
    lambda不能有默认参数,实参数目必须与形参数目相同;

2)组成

  [capture list] (parameter list)->return type{function body}
  我们可以忽略lambda的参数列表和返回类型,但是必须永远包含捕获列表和函数体,lambda根据函数体内的代码推断返回类型。

3)使用

1、传递参数:
auto add = [](const int &a, const int &b){return a + b};
std::cout << add(1,2) << std::endl;
2、使用捕获列表:
    int comp = 30;
    auto fun = \
        [comp]()\
        {\
            if(comp > 20)\
            {\
                std::cout << "Target bigger" << std::endl;\
            }\
       };
    fun();

lambda的捕获和返回:
  当定义一个lambda时,编译器生成一个与lambda对应的新的(未命名)的类类型。此处可理解为:当向函数传递一个lambda实例时,同时定义了一个新类型和该类型的一个对象:传递的参数是编译器生成的类类型的未命名对象。默认情况下,从lambda生成的类都包含一个对应该lambda所捕获的变量的数据成员,在对象创建时被初始化。

#include<iostream>

int main(int argc, char **argv)
{
    //值传递:被捕获的变量必须可拷贝,在创建时进行拷贝,而不是调用时。
    {
        int a = 10;
        auto copy = [a](){return a;};
        a = 0;
        auto b = copy();
        std::cout << " b = " << b << std::endl;
    }
    //引用捕获:必须确保被引用的对象在lambda执行时是存在的。
    {
        int a = 10;
        auto copy = [&a](){return a;};
        a = 0;
        auto b = copy();
        std::cout << " b = " << b << std::endl;
    }
    //隐式捕获:在[]写入'='或'&'告知编译器捕获方式为值捕获或引用捕获,编译器根据表达式中代码推断捕获列表
    {
        int a = 0;
        auto fun = [=](const int& tmp){return a > tmp;};
        std::cout << a << " > " << 100 << " ? " << fun(100) << std::endl;
    }
    return 0;
}

  返回:必须使用尾置返回类型。

{
    int a = -10;
    auto absolute = [](int tmp)->int {if(0 > tmp)return -tmp;return tmp;};
    a = absolute(a);
    std::cout << "  a = " << a << std::endl;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值