目录 1.function包装器 1.为什么需要function呢? 2.包装器可以很好的解决上面的问题 3.有了包装器,如何解决模板的效率低下,实例化多份的问题呢? 2.bind 1.什么是bind? 2.如何使用bind? 3.bind包装器的意义
1.function包装器
function包装器也叫作适配器。C++中的function本质是一个类模板,也是一个包装器
1.为什么需要function呢?
将具有相同调用形式的不同类型的可调用对象进行类型统一 若以三种不同的形式调用一个函数模板,会发生什么? 通过下面的程序验证,会发现useF函数模板实例化了三份 如此丰富的类型,可能会导致模板的效率低下!
ret = func ( x) ;
template < class F , class T > T useF ( F f, T x)
{ static int count = 0 ; cout << "count:" << ++ count << endl; cout << "count:" << & count << endl; return f ( x) ;
} double f ( double i)
{ return i / 2 ;
} struct Functor
{ double operator ( ) ( double d) { return d / 3 ; }
} ; int main ( )
{ cout << useF ( f, 11.11 ) << endl; cout << useF ( Functor ( ) , 11.11 ) << endl; cout << useF ( [ ] ( double d) -> double { return d / 4 ; } , 11.11 ) << endl; return 0 ;
}
2.包装器可以很好的解决上面的问题
template < class T > function; template < class Ret , class . . . Args>
class function < Ret ( Args. . . ) > ;
# include <functional>
int f ( int a, int b)
{ return a + b;
} struct Functor
{
public : int operator ( ) ( int a, int b) { return a + b; }
} ; class Plus
{
public : static int plusi ( int a, int b) { return a + b; } double plusd ( double a, double b) { return a + b; }
} ; int main ( )
{ std:: function< int ( int , int ) > func1 = f; cout << func1 ( 1 , 2 ) << endl; std:: function< int ( int , int ) > func2 = Functor ( ) ; cout << func2 ( 1 , 2 ) << endl; std:: function< int ( int , int ) > func3 = [ ] ( const int a, const int b) { return a + b; } ; cout << func3 ( 1 , 2 ) << endl; std:: function< int ( int , int ) > func4 = & Plus:: plusi; cout << func4 ( 1 , 2 ) << endl; std:: function< double ( Plus, double , double ) > func5 = & Plus:: plusd; cout << func5 ( Plus ( ) , 1.1 , 2.2 ) << endl; return 0 ;
}
3.有了包装器,如何解决模板的效率低下,实例化多份的问题呢?
# include <functional>
template < class F , class T >
T useF ( F f, T x)
{ static int count = 0 ; cout << "count:" << ++ count << endl; cout << "count:" << & count << endl; return f ( x) ;
} double f ( double i)
{ return i / 2 ;
} struct Functor
{ double operator ( ) ( double d) { return d / 3 ; }
} ; int main ( )
{ std:: function< double ( double ) > func1 = f; cout << useF ( func1, 11.11 ) << endl; std:: function< double ( double ) > func2 = Functor ( ) ; cout << useF ( func2, 11.11 ) << endl; std:: function< double ( double ) > func3 = [ ] ( double d) -> double { return d / 4 ; } ; cout << useF ( func3, 11.11 ) << endl; return 0 ;
}
2.bind
1.什么是bind?
它就像一个函数适配器,接受一个可调用对象,生成一个新的可调用对象来"适应"原对象的参数列表 一般而言,我们用它可以把一个原本接收N个参数的函数fn,通过绑定一些参数,返回一个接收M个参数的新函数 同时,使用std::bind函数还可以实现参数顺序调整等操作
template < class Fn , class . . . Args>
bind ( Fn&& fn, Args && . . . args) ;
template < class Ret , class Fn , class . . . Args>
bind ( Fn&& fn, Args && . . . args) ;
2.如何使用bind?
调用bind的一般形式:auto newCallable = bind(callable,arg_list) 其中,newCallable 本身是一个可调用对象,arg_list 是一个逗号分隔的参数列表 对应给定的callable 的参数。当调用newCallable时,newCallable会调用callable,并传给它arg_list中的参数 arg_list中的参数可能包含形如_n的名字,其中n是一个整数,这些参数是"占位符" 表示newCallable的参数,它们占据了传递给newCallable的参数的"位置" 数值n表示生成的可调用对象中参数的位置: _1为newCallable的第一个参数,_2为第二个参数,以此类推
using namespace placeholders; int Div ( int a, int b)
{ return a / b;
} int Plus ( int a, int b)
{ return a + b;
} int Mul ( int a, int b, double rate)
{ return a * b * rate;
} class Sub
{ public : int sub ( int a, int b) { return a - b; }
} ; int main ( )
{ function< int ( int , int ) > funcSub = bind ( & Sub:: sub, Sub ( ) , _1, _2) ; function< int ( int , int ) > funcMul = bind ( Mul, _1, _2, 1.5 ) ; auto bindFunc1 = bind ( Div, _1, _2) ; function< int ( int , int ) > bindFunc2 = bind ( Div, _2, _1) ; return 0 ;
}
3.bind包装器的意义
将一个函数的某些参数绑定为固定的值,让我们在调用时可以不用传递某些参数。 可以对函数参数的顺序进行灵活调整