c++ std function

本文介绍了C++11中的std::function特性,包括如何使用std::function替代传统函数指针,支持普通函数、Lambda表达式、bind表达式等多种类型的函数对象。此外还讨论了std::function在处理类成员函数指针和数据成员指针的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

C++ 11 新特性std::function

一、 一般函数指针

​ 函数指针,顾名思义,它就是指向函数的指针变量,该变量指向函数。

void print_num(int i)
{
    std::cout << i << '\n';
}
void main()
{
    //一般函数指针
    typedef void(*pfunc1)(int);
    pfunc1 func_1;
    func_1 = print_num;
    func_1(1);
    return;
}

二、类成员函数指针

​ 类成员函数指针不同于一般函数指针,因为类成员函数都隐含了一个this指针。编译器一般也不容许类成员函数赋值给一般函数指针。在指针前加入一个域限定符,并指定成员函数对应的类的实例。

class Foo {
public:
    Foo(int num) : num_(num) {}
    void print_add(int i) { std::cout << num_+i << '\n'; }
    int num_;
};
void main()
{
    //类成员函数指针
    typedef void (Foo::*pfunc2)(int);
    Foo foo2(2);
    pfunc2 func2 = &Foo::print_add;
    (foo2.*func2)(2);
    return;
}

​ 对于静态类成员函数,实际上就是一个作用域在类内部的普通函数,没有隐含的this指针。

class Foo {
public:
    Foo(int num) : num_(num) {}
    void print_add(int i)  { std::cout << num_+i << '\n'; }
    static void print_add2(int i)  {
        std::cout << "I am static" << '\n';
    }
    int num_;
};
void main()
{
    func_1 = &Foo::print_add2;
    func_1(2);
    return;
}

三、C++ 11特性 std::function

定义

template< class R, class... Args >
class function<R(Args...)>;

std::function实现了一套类型消除机制,可以统一处理不同的函数对象类型。以前我们使用函数指针来完成这些;现在我们可以使用更安全的std::function来完成这些任务

  • 类模板 std::function 是通用多态函数封装器。
  • std::function 的实例能存储、复制及调用任何可调用 (Callable) 目标——函数、 lambda 表达式、 bind 表达式或其他函数对象,还有指向成员函数指针和指向数据成员指针。
  • 它也是对 C++ 中现有的可调用实体的一种类型安全的包裹(相对来说,函数指针的调用不是类型安全的)

3.1 普通函数

void print_num(int i)
{
    std::cout << i << '\n';
}
void main()
{
    std::function<void(int)> f_display = print_num;
    f_display(-9);
    return;
}

3.2 Lambda函数

void print_num(int i)
{
    std::cout << i << '\n';
}
void main()
{
    std::function<void()> f_display_42 = []() { print_num(42); };
    f_display_42();
    return;
}

3.3 std::bind返回值

void print_num(int i)
{
    std::cout << i << '\n';
}
void main()
{
    std::function<void()> f_display_31337 = std::bind(print_num, 31337);
    f_display_31337();
    return;
}

3.4 类成员函数

class Foo {
public:
    Foo(int num) : num_(num) {}
    void print_add(int i)  { std::cout << num_+i << '\n'; }
    static void print_add2(int i)  {
        std::cout << "I am static" << '\n';
    }
    int num_;
};
void main()
{
    std::function<void(Foo&, int)> f_add_display = &Foo::print_add;
    Foo foo(314159);
    f_add_display(foo, 1);
    return;
}

3.5 类的成员变量

class Foo {
public:
    Foo(int num) : num_(num) {}
    void print_add(int i)  { std::cout << num_+i << '\n'; }
    static void print_add2(int i)  {
        std::cout << "I am static" << '\n';
    }
    int num_;
};
void main()
{
	Foo foo(314159);
    std::function<int(Foo &)> f_num = &Foo::num_;
    std::cout << "num_: " << f_num(foo) << '\n';
    return;
}

3.6 重载运算符()

class PrintNum {
public:
    void operator()(int i)
    {
        std::cout << i << '\n';
    }
};
void main()
{
    std::function<void(int)> f_display_obj = PrintNum();
    f_display_obj(18);
    return;
}

3.7 对于重载函数的使用

因为std::function可以用任何对象初始化,因为它的构造函数是模板化的,它与传递给std::function的模板参数无关。因此std::function无法识别重载函数。

class Foo {
public:
    Foo(int num) : num_(num) {}
    void print_add(int i)  { std::cout << num_+i << '\n'; }
    void print_add(int i,int q)  { std::cout << num_+i << '\n'; }
    static void print_add2(int i)  {
        std::cout << "I am static" << '\n';
    }
    int num_;
};
void main()
{
    Foo foo(314159);
    using std::placeholders::_1;
    std::function<void(int)> f_add_display3 = std::bind((void(Foo::*)(int))&Foo::print_add, &foo, _1 );
    f_add_display3(3);
    return;
}

四、Radio Sw 使用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值