C++标准库笔记

1. std::bind函数

原理

bind函数的返回值是一个函数对象/仿函数.

  • bind函数(包装器/适配器)能够将用户提供的需要一个参数的函数调整为不需要参数的函数对象。需要的时候,绑定的值存储在函数对象中,自动地传递给用户指定的函数

  • 绑定一个参数也可以将类的成员函数调整为不需要参数的函数对象。正如你所知,非静态的成员函数都有一个隐式的this指针参数。这就意味着在函数指针内部需要绑定一个指向该类的一个对象的指针,

或者隐式的this指针可以通过给函数对象传入一个显示的参数:

  • 函数对象通常同时使用提前绑定的参数和调用时提供的参数。这个过程可以通过给成员函数绑定参数来实现:

使用

在c++11之前,要绑定某个函数、函数对象或者成员函数的不同参数值需要用到不同的转换器,如bind1st、bind2nd、fun_ptr、mem_fun和mem_fun_ref等.在c++11中,绑定参数的方法得以简化.c++11提供了”一站式”绑定模板bind,其用法为:

#include <functional>
std::bind(待绑定的函数对象/函数指针/成员函数指针,参数绑定值1,参数绑定值2,...,参数绑定值n);

class JK
{
public:
	JK(){}

	virtual void add()=0;
};

void JK::add()
{
	std::cout << "add";
}

class Child: public JK
{
public:
	Child(const std::string& n):name(n)
	{
	}

	Child & operator=(const Child & rth)
	{
		if (this == &rth)
		{
			return *this;
		}
		delete p;
		p = rth.p;

		return *this;
	}
	virtual void add();

private:
	const std::string& name;
	void *p;
};

void Child::add()
{
	JK::add();
	std::cout << name<< std::endl;
}

//main()
std::string var = "list";
Child k(var);
k.add();
var = "list5";
k.add();

std::function<void()> f = std::bind(&Child::add, k);
f();

2. std::function

function是一组函数对象包装类的模板,实现了一个泛型的回调机制。function与函数指针比较相似,优点在于它允许用户在目标的实现上拥有更大的弹性,即目标既可以是普通函数,也可以是函数对象和类的成员函数,而且可以给函数添加状态。 声明一个function时,需要给出所包装的函数对象的返回值类型和各个参数的类型。比如,声明一个function,它返回一个bool类型并接受一个int类型和一个float类型的参数,可以像下面这样:

function<bool (int, float)> f;

#include <functional>
#include <iostream>
 
struct Foo {
    Foo(int num) : num_(num) {}
    void print_add(int i) const { std::cout << num_+i << '\n'; }
    int num_;
};
 
void print_num(int i)
{
    std::cout << i << '\n';
}
 
struct PrintNum {
    void operator()(int i) const
    {
        std::cout << i << '\n';
    }
};
 
int main()
{
    // store a free function
    std::function<void(int)> f_display = print_num;
    f_display(-9);
 
    // store a lambda
    std::function<void()> f_display_42 = []() { print_num(42); };
    f_display_42();
 
    // store the result of a call to std::bind
    std::function<void()> f_display_31337 = std::bind(print_num, 31337);
    f_display_31337();
 
    // store a call to a member function
    std::function<void(const Foo&, int)> f_add_display = &Foo::print_add;
    const Foo foo(314159);
    f_add_display(foo, 1);
    f_add_display(314159, 1);
 
    // store a call to a data member accessor
    std::function<int(Foo const&)> f_num = &Foo::num_;
    std::cout << "num_: " << f_num(foo) << '\n';
 
    // store a call to a member function and object
    using std::placeholders::_1;
    std::function<void(int)> f_add_display2 = std::bind( &Foo::print_add, foo, _1 );
    f_add_display2(2);
 
    // store a call to a member function and object ptr
    std::function<void(int)> f_add_display3 = std::bind( &Foo::print_add, &foo, _1 );
    f_add_display3(3);
 
    // store a call to a function object
    std::function<void(int)> f_display_obj = PrintNum();
    f_display_obj(18)
}

3. C++11 新特性之std::thread

从C++11开始,C++标准库已经支持了线程库了.

#include <thread>
//1. 直接使用函数

void thread1_process(int code)
{
    std::cout << "code: " << code << std::endl;
}

int code  = 0; // get code from somewhere
std::thread thread1(thread1_process, code);
thread1.join(); // 等待线程结束
//tread1.detach(); // 将线程脱离thread1的管理


//2. 使用类成员函数
struct Task
{
 void doSomething(int task_type) {
    std::cout << "task_type: " << task_type<< std::endl; 
    // TODO
 }
};
Task task1;
std::thread thread2(&Task::doSomething, &task1, 1);
thread2.join(); // 等待线程结束
//tread2.detach(); // 将线程脱离thread2的管理


//3. 使用std::bind
Task task2;
std::thread thread3(std::bind(&Task::doSomething, &task2, 2));
thread3.join(); // 等待线程结束
//tread3.detach(); // 将线程脱离thread3的管理

//4. 使用lambda表达式
std::thread thread4([](){
    std::cout << "lambda thread called." <<std::enld; 
});
thread4.join(); // 等待线程结束
//tread4.detach(); // 将线程脱离thread4的管理

4. 智能指针

C++11 有2大类型智能指针:shared_ptr, unique_ptr

前者与boost::shared_ptr差不多,后者拥有严格的所有权,用于避免内存泄漏。

5. 算法

for_each

find_if

参考:

  1. my coding.net
  2. 定义
  3. https://www.cnblogs.com/sixue/p/4013766.html
  4. C++11 bind函数实现原理图
  5. https://www.cnblogs.com/milanleon/p/7491180.html
  6. https://www.cnblogs.com/yyxt/p/3987717.html
  7. std::function
  8. std::thread