函数调用运算符与function类模板(C++新经典笔记)

几个概念:

  1. 函数调用运算符:()
    1. 调用函数的方法是,首先是函数名,后面跟(),如果函数有参数,在函数调用位置的函数名后的圆括号中给出实参,在函数定义位置函数名后的圆括号中给出形参。
    2. 如果在类中重载了(),可以像调用函数一样调用该类的对象。使用方法是,定义一个该类对象,在对象()中增加实参列表。注意函数对象和类构造函数的区分。
  2. 如果两个函数(可调用对象)的形参和返回值相同,可以说两个函数的调用形式相同。一种调用形式对应一种函数类型。
  3. 如果希望把可调用对象的指针保存起来方便后期调用,一个想法是利用函数指针。函数的指针自然可以用函数指针保存,但系统不会把重载了函数调用运算符的类及其对象看成函数指针。
  4. C++11引入了function类模板,可以用来包装可调用对象。这时,函数、函数对象都可以识别。但如果函数有重载的情况,编译就会报错。这时可以通过定义一个函数指针解决。
// biggerthanzero.h
#pragma once
#include <iostream>

// 定义一个不输出负数的类
class biggerthanzero {
public:
    // 默认构造函数
    biggerthanzero() = default;

    // 带参数的构造函数,打印一条消息
    explicit biggerthanzero(int i) {
        std::cout << "The construct func\n";
    }

    // 函数调用运算符重载,接收一个整数参数
    int operator()(int value) const {
        return (value < 0) ? 0 : value;
    }
};

// 声明一个函数,接受一个整数参数并返回处理后的结果
int echovalue(int value);

// 重载,声明一个无参数的函数
void echovalue();
// biggerthanzero.cpp
#include <iostream>

int echovalue(int value) {
    std::cout << value << std::endl;  
    return value;                   
}

void echovalue() {
    std::cout << "重载" << std::endl; 
}
// main.cpp
#include "biggerthanzero.h"  // 包含自定义类的头文件
#include <iostream>
#include <map>
#include <functional>

int main() {
    // 创建一个biggerthanzero类的对象,初始化值为1,注意和函数调用运算符的区别
    biggerthanzero obj(1);

    // 调用biggerthanzero对象的重载运算符(),并输出结果
    std::cout << obj(23) << std::endl;

    // 调用echovalue函数并输出结果
    std::cout << echovalue(-1) << std::endl;

    // 使用函数指针调用echovalue函数
    int(*p)(int) = echovalue;
    int c = (*p)(23);

    // 使用std::map来存储函数指针
    std::map<std::string, int(*)(int)> myoper;
    myoper.insert({"ev", echovalue});
    // 直接将类或对象作为函数指针是不允许的,因此需要使用std::function

    // 定义函数指针,并用std::function封装
    std::function<int(int)> f1 = p;  // 因为有重载,用函数指针初始化std::function
    std::function<int(int)> f2 = obj;        // 用类对象初始化std::function
    std::function<int(int)> f3 = biggerthanzero(); // 使用默认构造函数初始化std::function

    // 使用std::map来存储std::function
    std::map<std::string, std::function<int(int)>> myoper2;
    myoper2.insert({"ev", f1});
    myoper2.insert({"bt", f2});
    myoper2.insert({"bt2", f3});

    // 通过std::function调用存储的函数
    std::cout << myoper2["ev"](1)  << std::endl;
    std::cout << myoper2["bt"](2) << std::endl;
    std::cout << myoper2["bt2"](-1)  << std::endl;

    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值