C++11 - std::function简要介绍以及可包装函数的几种形式总结

1 std::function

函数模板形式:

template <class T>函数;//未定义
模板<class Retclass ... Args> class function <Ret(Args ...>;

1.1 函数模板说明

std::function是一个函数包装器模板,该函数包装器模板可以包装任意可以调用的元素,其包装器的类型只依赖于其调用特征,而不依赖于可调用元素自身的类型。

std::function可包装下列可调用元素类型:

  • 函数
  • 函数指针
  • 类成员函数
  • 任意类型的函数可调用对象(比如重载了operator()操作符并且拥有函数闭包的函数体对象)

std::function对象可被拷贝和转移,并且可以使用指定的调用特征来直接调用目标元素。
当std::function对象未包裹任何实际的可调用元素,调用该std::function对象将抛出std::bad_function_call异常。

1.2 模板参数说明

  • T : 通用类型,但实际通用类型模板并没有被定义,只有当T的类型为形如Ret(Args…)的函数类型才能工作;
  • Ret :调用函数返回值的类型;
  • Args:函数参数类型,对于指向成员函数的指针,第一个参数应该是指向该成员函数的引用或者对象。

2 std::function可包装的几种函数形式总结

2.1 包装普通函数和静态函数

2.1.1 非模板类型

代码示例:

#include <iostream>
#include <functional>
#include <memory>

using namespace std;

int Add(int a, int b)
{
        std::cout << "普通函数被调用,结果为:" << a + b << std::endl;
        return a + b;
}

static int StaticAdd(int a, int b)
{
        std::cout << "静态函数被调用,结果为:" << a + b << std::endl;
        return a + b;
}


int main()
{
        // 1 普通函数
        std::function<int(int, int)> addFunc1 = Add;
        addFunc1(1, 2);

        // 2 普通函数指针
        std::function<int(int, int)> addFunc2 = &Add;
        addFunc2(3, 4);

        // 3 静态函数
        std::function<int(int, int)> staticAddFunc1 = StaticAdd;
        staticAddFunc1(5, 6);

        // 4 静态函数指针
        std::function<int(int, int)> staticAddFunc2 = &StaticAdd;
        staticAddFunc2(7, 8);

        getchar();
        return 0;
}

2.1.2 模板类型

代码示例:

#include <iostream>
#include <functional>
#include <memory>

using namespace std;

template <class T>
T Add(T a, T b)
{
        std::cout << "普通模板函数被调用,结果为:" << a + b << std::endl;
        return a + b;
}

template <class T>
static T StaticAdd(T a, T b)
{
        std::cout << "静态模板函数被调用,结果为:" << a + b << std::endl;
        return a + b;
}


int main()
{
        // 1 普通函数
        std::function<int(int, int)> addFunc1 = Add<int>;
        addFunc1(1, 2);

        // 2 普通函数指针
        std::function<int(int, int)> addFunc2 = &Add<int>;
        addFunc2(3, 4);

        // 3 静态函数
        std::function<int(int, int)> staticAddFunc1 = StaticAdd<int>;
        staticAddFunc1(5, 6);

        // 4 静态函数指针
        std::function<int(int, int)> staticAddFunc2 = &StaticAdd<int>;
        staticAddFunc2(7, 8);

        getchar();
        return 0;
}

2.2 包装类成员函数和类静态函数

2.2.1 非模板类型

代码示例:

#include <iostream>
#include <functional>
#include <memory>

using namespace std;

class A
{
public:
        typedef std::shared_ptr<A> ptr;
        A()
        {
        };
        virtual~A()
        {

        };
public:
        int A_Add_Public(int a, int b)
        {
                std::cout << "类公有成员函数被调用,结果为:" << a + b << std::endl;
                return a + b;
        }

        static int A_Add_Static(int a, int b)
        {
                std::cout << "类静态函数被调用,结果为:" << a + b << std::endl;
                return a + b;
        }

public:
        int m_Value = 20;
};


int main()
{
        // 1 类公有成员函数
        A m_a;
        std::function<int(int, int)> addFunc1 = std::bind(&A::A_Add_Public, &m_a, std::placeholders::_1, std::placeholders::_2);
        addFunc1(1, 2);

        // 2 类静态函数
        std::function<int(int, int)> addFunc2 = &A::A_Add_Static;
        addFunc2(1, 2);

        getchar();
        return 0;
}

2.2.2 模板类型

代码示例:

#include <iostream>
#include <functional>
#include <memory>

using namespace std;

class A
{
public:
        typedef std::shared_ptr<A> ptr;
        A()
        {
        };
        virtual~A()
        {

        };
public:
        template <class T>
        T A_Add_Public(T a, T b)
        {
                std::cout << "类公有模板成员函数被调用,结果为:" << a + b << std::endl;
                return a + b;
        }

        template <class T>
        static T A_Add_Static(T a, T b)
        {
                std::cout << "类静态模板函数被调用,结果为:" << a + b << std::endl;
                return a + b;
        }

public:
        int m_Value = 20;
};


int main()
{
        // 1 类公有成员函数
        A m_a;
        std::function<int(int, int)> addFunc1 = std::bind(&A::A_Add_Public<int>, &m_a, std::placeholders::_1, std::placeholders::_2);
        addFunc1(1, 2);

        // 2 类静态函数
        std::function<int(int, int)> addFunc2 = &A::A_Add_Static<int>;
        addFunc2(1, 2);

        getchar();
        return 0;
}

2.3 包装Lambda表达式

代码示例:

#include <iostream>
#include <functional>
#include <memory>

using namespace std;


int main()
{
	// 1 lambda表达式
	std::function<int(int, int)> addFunc1 = [](int a, int b) ->int {
		std::cout << "lambda表达式被调用,结果为:" << a + b << std::endl;
		return a + b;
	};
	addFunc1(1, 2);

	getchar();
	return 0;
}

2.4 包装类重载操作符()函数

2.4.1 非模板类型

代码示例:

#include <iostream>
#include <functional>
#include <memory>

using namespace std;

class A
{
public:
        typedef std::shared_ptr<A> ptr;
        A()
        {
        };
        virtual~A()
        {

        };
public:
        int operator()(int a, int b)
        {
                std::cout << "类重载操作符()函数被调用,结果为:" << a + b << std::endl;
                return a + b;
        }

public:
        int m_Value = 20;
};


int main()
{
        // 1 类重载操作符()函数
        std::function<int(int, int)> addFunc1 = A();
        addFunc1(1, 2);

        getchar();
        return 0;
}

2.4.2 模板类型

代码示例:

#include <iostream>
#include <functional>
#include <memory>

using namespace std;

template <class T>
class A
{
public:
        typedef std::shared_ptr<A> ptr;
        A()
        {
        };
        virtual~A()
        {

        };
public:
        T operator()(T a, T b)
        {
                std::cout << "类重载操作符()模板函数被调用,结果为:" << a + b << std::endl;
                return a + b;
        }

public:
        int m_Value = 20;
};


int main()
{
        // 1 类重载操作符()函数
        std::function<int(int, int)> addFunc1 = A<int>();
        addFunc1(1, 2);

        getchar();
        return 0;
}

2.5 包装类共有成员变量

代码示例:

#include <iostream>
#include <functional>
#include <memory>

using namespace std;

class A
{
public:
        typedef std::shared_ptr<A> ptr;
        A()
        {
        };
        virtual~A()
        {

        };
public:
        int Add()
        {
                return m_Value;
        }

public:
        int m_Value = 20;
};


int main()
{
        // 1 类共有成员变量
        std::function<int(A&)> A_Value = &A::m_Value;

        A m_a;
        std::cout << "m_a对象的成员m_Value的值为:" << A_Value(m_a) << std::endl;


        getchar();
        return 0;
}

大家有兴趣可以访问我的个人站:http://www.stubbornhuang.com

### 回答1: std::functionC++11的一个函数对象包装器,它可以用来封装各种可调用实体,包括函数指针、函数对象以及类成员函数等。它的主要作用是将函数或者函数对象存储起来,以便稍后调用。 std::function的使用方法很简单,首先需要声明一个std::function对象,然后通过赋值或者绑定一个可调用实体来进行初始化。在调用时,可以像调用普通函数一样使用该std::function对象。 例如,假设我们有一个函数func,它的参数是一个int类型的整数,返回值是一个字符串。我们可以先定义一个std::function对象funcWrapper,然后将func赋值给它,接着通过调用funcWrapper来使用func。 std::bind是C++11的一个函数对象适配器,它可以用来修改或者重排函数的参数顺序。它接受一个可调用实体以及一系列参数,然后返回一个新的函数对象。这个新的函数对象可以像原始的可调用实体一样进行调用。 std::bind的使用方法也很简单,首先需要声明一个std::function对象,然后使用std::bind将可调用实体以及参数绑定到该std::function对象上。在调用时,可以像调用普通函数一样使用该std::function对象。 例如,我们有一个函数add,它接受两个整数作为参数,返回它们的和。我们可以使用std::bind将add函数绑定到一个std::function对象上,并将其一个参数设置为常数10。然后,在调用时,我们只需要提供另一个参数即可。 综上所述,std::functionstd::bind是C++11非常有用的函数对象封装器和函数对象适配器。它们可以帮助我们更灵活地处理函数对象,并且可以简化代码的编写和阅读。 ### 回答2: std::functionstd::bind是C++11引入的函数对象的概念和相关功能的标准库组件。 首先,std::function 是一个通用的函数封装器,可以包装各种可调用对象,比如普通函数函数指针、成员函数、lambda表达式等。通过使用std::function,我们可以像使用普通函数一样,对这些可调用对象进行传递、存储等操作。例如: ```cpp #include <iostream> #include <functional> void printHello() { std::cout << "Hello\n"; } int add(int a, int b) { return a + b; } int main() { std::function<void()> func1 = printHello; func1(); // 输出 Hello std::function<int(int, int)> func2 = add; std::cout << func2(1, 2) << std::endl; // 输出 3 return 0; } ``` 其次,std::bind 是一个函数适配器,可以将可调用对象与其参数进行绑定,生成一个新的可调用对象。通过使用std::bind,我们可以将函数的部分参数绑定为特定的值,从而修改函数的行为或者改变函数的接口。例如: ```cpp #include <iostream> #include <functional> void printSum(int a, int b) { std::cout << "Sum: " << a + b << std::endl; } int main() { auto bindFunc = std::bind(printSum, 1, std::placeholders::_1); bindFunc(2); // 输出 Sum: 3 return 0; } ``` 在上面的例子,使用std::bind将printSum函数的第一个参数绑定为1,生成了一个新的可调用对象bindFunc。当调用bindFunc(2)时,实际上就是调用了printSum(1, 2),输出了"Sum: 3"。 通过使用std::functionstd::bind,我们可以更加灵活地处理函数对象和参数的相关操作,增强了C++函数式编程的能力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

HW140701

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值