Boost::bind使用详解,boostbind使用详解

Boost::bind使用详解,boostbind使用详解

1.Boost::bind

  在STL中,我们经常需要使用bind1st,bind2st函数绑定器和fun_ptr,mem_fun等函数适配器,这些函数绑定器和函数适配器使用起来比较麻烦,需要根据是全局函数还是类的成员函数,是一个参数还是多个参数等做出不同的选择,而且有些情况使用STL提供的不能满足要求,所以如果可以我们最好使用boost提供的bind,它提供了统一的接口,提供了更多的支持,比如说它增加了shared_ptr,虚函数,类成员的绑定。

bind()方法用法详解:

使用jquery也有近1年了,今天在看国外大牛代码突然发现一个地方没看明白,代码如下

使用jquery也有近1年了,今天在看国外大牛代码突然发现一个地方没看明白,代码如下

1.Boost::bind

  在STL中,我们经常需要使用bind1st,bind2st函数绑定器和fun_ptr,mem_fun等函数适配器,这些函数绑定器和函数适配器使用起来比较麻烦,需要根据是全局函数还是类的成员函数,是一个参数还是多个参数等做出不同的选择,而且有些情况使用STL提供的不能满足要求,所以如果可以我们最好使用boost提供的bind,它提供了统一的接口,提供了更多的支持,比如说它增加了shared_ptr,虚函数,类成员的绑定。

2.bind的工作原理

  bind并不是一个单独的类或函数,而是非常庞大的家族,依据绑定的参数的个数和要绑定的调用对象的类型,总共有数十种不同的形式,编译器会根据具体的绑定代码制动确定要使用的正确的形式,bind的基本形式如下:

图片 1图片 2

1 template<class R,class F> bind(F f);
2 template<class R,class F,class A1> bind(F f,A1 a1);
3 namespace
4 {
5 boost::arg<1> _1;
6 boost::arg<2> _2;
7 boost::arg<3> _3;
8 …..                                     //其他6个占位符
9 };

View Code

  bind接收的第一个参数必须是一个可调用的对象f,包括函数函数指针函数对象、和成员函数指针,之后bind最多接受9个参数参数数量必须与f的参数数量相等,这些参数被传递给f作为入参。
绑定完成后,bind返回一个函数对象,它内部保存了f的拷贝,具有operator()返回值类型自动推导f的返回类型。在发生调用时这个函数对象将把之前存储的参数转发给f完成调用。例如,有一个函数func,它的形式是:

1 func(a1,a2);

那么,他将等价于一个具有无参operator()的bind函数对象调用:

1 bind(func,a1,a2)();

  这是bind最简单的形式,bind表达式存储了func和a1、a2的拷贝,产生了一个临时函数对象。因为func接收两个参数,而a1和a2的拷贝传递给func完成真正的函数调用。

  bind的真正威力在于它的占位符,它们分别定义为_1,_2,_3,一直到
_9
,位于一个匿名的名字空间。占位符可以取代bind参数的位置,在发生调用时接受真正的参数占位符的名字表示它在调用式中的顺序,而在绑定的表达式中没有没有顺序的要求,_1不一定必须第一个出现,也不一定只出现一次,例如:

1 bind(func,_2,_1)(a1,a2);

  返回一个具有两个参数的函数对象,第一个参数将放在func的第二个位置,而第二个参数则放在第一个位置,调用时等价于:

1 func(a2,a1);

此方法是使用比较频繁的方法之一,虽然在API手册上有着对方法的介绍,但是由于语言简短,例子不够详细,可能会造成不能够完全准确的掌握bind()方法的使用,下面就结合实例介绍一下此方法的使用。

  $(window).bind(‘load.jcarousel’, function() { windowLoaded = true;
});

  $(window).bind(‘load.jcarousel’, function() { windowLoaded = true;
});

2.bind的工作原理

  bind并不是一个单独的类或函数,而是非常庞大的家族,依据绑定的参数的个数和要绑定的调用对象的类型,总共有数十种不同的形式,编译器会根据具体的绑定代码制动确定要使用的正确的形式,bind的基本形式如下:

图片 31
template<class R,class F> bind(F f); 2 template<class R,class
F,class A1> bind(F f,A1 a1); 3 namespace 4 { 5 boost::arg<1>
_1; 6 boost::arg<2> _2; 7 boost::arg<3> _3; 8 …..
//其他6个占位符 9 }; View
Code

  bind接收的第一个参数必须是一个可调用的对象f,包括函数函数指针函数对象、和成员函数指针,之后bind最多接受9个参数参数数量必须与f的参数数量相等,这些参数被传递给f作为入参。
绑定完成后,bind返回一个函数对象,它内部保存了f的拷贝,具有operator()返回值类型自动推导f的返回类型。在发生调用时这个函数对象将把之前存储的参数转发给f完成调用。例如,有一个函数func,它的形式是:

1 func(a1,a2);

那么,他将等价于一个具有无参operator()的bind函数对象调用:

1 bind(func,a1,a2)();

  这是bind最简单的形式,bind表达式存储了func和a1、a2的拷贝,产生了一个临时函数对象。因为func接收两个参数,而a1和a2的拷贝传递给func完成真正的函数调用。

  bind的真正威力在于它的占位符,它们分别定义为_1,_2,_3,一直到
_9
,位于一个匿名的名字空间。占位符可以取代bind参数的位置,在发生调用时接受真正的参数占位符的名字表示它在调用式中的顺序,而在绑定的表达式中没有没有顺序的要求,_1不一定必须第一个出现,也不一定只出现一次,例如:

1 bind(func,_2,_1)(a1,a2);

  返回一个具有两个参数的函数对象,第一个参数将放在func的第二个位置,而第二个参数则放在第一个位置,调用时等价于:

1 func(a2,a1);

3.常用的函数对象工具

(1)bind1st,bind2st函数绑定器,把二元函数对象变为一元函数对象
(2)mem_fun,把成员函数变为函数对象
(3)fun_ptr,把一般的全局函数变为函数对象
(4)boost::bind(),包含了以上所有的功能

语法格式:

  也许我对jQuery的了解不多吧,自己也就看过一本jQuery的入门书,然后总是在工作中学习,碰着问题了就总结一点,学习一点…嘿嘿,也许为什么动不动公司招人就是1年以上工作经验什么的,确实实战才是能让人最快速提高的。

  也许我对jQuery的了解不多吧,自己也就看过一本jQuery的入门书,然后总是在工作中学习,碰着问题了就总结一点,学习一点…嘿嘿,也许为什么动不动公司招人就是1年以上工作经验什么的,确实实战才是能让人最快速提高的。

3.常用的函数对象工具

(1)bind1st,bind2st函数绑定器,把二元函数对象变为一元函数对象
(2)mem_fun,把成员函数变为函数对象
(3)fun_ptr,把一般的全局函数变为函数对象
(4)boost::bind(),包含了以上所有的功能

4.bind与其他函数对象工具区别

$(selector).bind(type,[data],function(eventObject))

  找到jQuery API,解释如下:

  找到jQuery API,解释如下:

4.bind与其他函数对象工具区别

4.1 区别与mem_fun和fun_ptr

图片 4图片 5

 1 #include <functional>
 2 #include <iostream>
 3 #include <string>
 4 #include "boost/bind.hpp"
 5 class some_class 
 6 {
 7 public:      
 8     void print_string(const std::string& s) const
 9     {    
10         std::cout << s << '\n'; 
11     }
12     void print_classname()
13     {
14         std::cout << "some_class" << std::endl;
15     }
16 };
17 void print_string(const std::string s) 
18 {  std::cout << s << '\n';
19 }
20 void print_functionname()
21 {
22     std::cout << "Print_functionname" <<std::endl;
23 }
24 int main() 
25 {  
26     std::ptr_fun(&print_string)("hello1");
27     //std::ptr_fun<void>(&print_functionname);
28     some_class sc0;
29     std::mem_fun_ref(&some_class::print_classname)(sc0);
30     std::mem_fun_ref<void,some_class>(&some_class::print_classname)(sc0);
31     //std::mem_fun1_ref<void,some_class,const std::stirng>(&some_class::print_string)(sc0,"hello2");
32 
33     (boost::bind(&print_string,_1))("Hello func!");  
34     boost::bind(&print_functionname);
35     some_class sc;  
36     (boost::bind(&some_class::print_classname,_1)(sc));
37     (boost::bind(&some_class::print_string,_1,_2))(sc,"Hello member!");
38 }

View Code

此方法可以为所有匹配元素的特定事件绑定事件处理函数,例如:

1.一次可以绑定多个事件。如:

1.一次可以绑定多个事件。如:

4.1 区别与mem_fun和fun_ptr

图片 6 1
#include <functional> 2 #include <iostream> 3 #include
<string> 4 #include “boost/bind.hpp” 5 class some_class 6 { 7
public: 8 void print_string(const std::string& s) const 9 { 10
std::cout << s << ‘\n’; 11 } 12 void print_classname() 13
{ 14 std::cout << “some_class” << std::endl; 15 } 16 }; 17
void print_string(const std::string s) 18 { std::cout << s
<< ‘\n’; 19 } 20 void print_functionname() 21 { 22 std::cout
<< “Print_functionname” <<std::endl; 23 } 24 int main() 25
{ 26 std::ptr_fun(&print_string)(“hello1″); 27
//std::ptr_fun<void>(&print_functionname); 28 some_class sc0;
29 std::mem_fun_ref(&some_class::print_classname)(sc0); 30
std::mem_fun_ref<void,some_class>(&some_class::print_classname)(sc0);
31 //std::mem_fun1_ref<void,some_class,const
std::stirng>(&some_class::print_string)(sc0,”hello2”); 32 33
(boost::bind(&print_string,_1))(“Hello func!”); 34
boost::bind(&print_functionname); 35 some_class sc; 36
(boost::bind(&some_class::print_classname,_1)(sc)); 37
(boost::bind(&some_class::print_string,_1,_2))(sc,”Hello member!”);
38 } View Code

4.2 区别与bind1st和bind2st

图片 7图片 8

 1 #include <functional>
 2 #include <iostream>
 3 #include <string>
 4 #include <vector>
 5 #include <algorithm>
 6 #include "boost/bind.hpp"
 7 void main()
 8 {
 9     std::vector<int> ints;
10     ints.push_back(7);
11     ints.push_back(4);
12     ints.push_back(12);
13     ints.push_back(10);
14     int count=std::count_if(ints.begin(),  
15         ints.end(), 
16         boost::bind(std::logical_and<bool>(),boost::bind(std::greater<int>(),_1,5),boost::bind(std::less_equal<int>(),_1,10))
17         );
18     std::cout << count << '\n';
19     std::vector<int>::iterator int_it=std::find_if(ints.begin(),  
20         ints.end(),  
21         boost::bind(std::logical_and<bool>(),boost::bind(std::greater<int>(),_1,5),boost::bind(std::less_equal<int>(),_1,10))
22         );
23     if (int_it!=ints.end()) 
24     {  std::cout << *int_it << '\n';}
25 
26 }

View Code

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>脚本之家</title>
<style type="text/css">
div{
 width:150px;
 height:40px;
 background-color:blue;
}
</style>
<script type="text/javascript" src="mytest/jQuery/jquery-1.8.3.js"></script>
<script type="text/javascript">
$(document).ready(function(){
 $("#bt").bind("click",function(){$("div").text("脚本之家")}) 
})
</script>
</head>
<body>
<div>您好</div>
<input type="button" id="bt" value="点击测试代码" />
</body>
</html>

复制代码 代码如下:

复制代码 代码如下:

4.2 区别与bind1st和bind2st

图片 9 1
#include <functional> 2 #include <iostream> 3 #include
<string> 4 #include <vector> 5 #include <algorithm>
6 #include “boost/bind.hpp” 7 void main() 8 { 9 std::vector<int>
ints; 10 ints.push_back(7); 11 ints.push_back(4); 12
ints.push_back(12); 13 ints.push_back(10); 14 int
count=std::count_if(ints.begin(), 15 ints.end(), 16
boost::bind(std::logical_and<bool>(),boost::bind(std::greater<int>(),_1,5),boost::bind(std::less_equal<int>(),_1,10))
17 ); 18 std::cout << count << ‘\n’; 19
std::vector<int>::iterator int_it=std::find_if(ints.begin(), 20
ints.end(), 21
boost::bind(std::logical_and<bool>(),boost::bind(std::greater<int>(),_1,5),boost::bind(std::less_equal<int>(),_1,10))
22 ); 23 if (int_it!=ints.end()) 24 { std::cout << *int_it
<< ‘\n’;} 25 26 } View
Code

4.3 区别传ref和传instance

图片 10图片 11

 1 // bind instance or reference
 2 #include <functional>
 3 #include <iostream>
 4 #include <string>
 5 #include <vector>
 6 #include <algorithm>
 7 #include "boost/bind.hpp"
 8 class tracer 
 9 {
10 public: 
11     tracer() {    std::cout << "tracer::tracer()\n";  } 
12     tracer(const tracer& other) {    std::cout << "tracer::tracer(const tracer& other)\n";  } 
13     tracer& operator=(const tracer& other)
14     {    std::cout <<      "tracer& tracer::operator=(const tracer& other)\n";    return *this;  } 
15     ~tracer() {    std::cout << "tracer::~tracer()\n"; 
16     } 
17     void print(const std::string& s) const
18     {    std::cout << s << '\n';  }
19 };
20 
21 void main()
22 {
23     tracer t;
24     boost::bind(&tracer::print,t,_1)(std::string("I'm called on a copy of t\n"));
25     tracer t1;
26     boost::bind(&tracer::print,boost::ref(t1),_1)(  std::string("I'm called directly on t\n"));
27 
28 }

View Code

以上代码中,当点击按钮的时候,会将div元素中的文本设置“脚本之家”。

$(‘#foo’).bind({
click: function() {
// do something on click
},
mouseenter: function() {
// do something on mouseenter
}
});  

$(‘#foo’).bind({
click: function() {
// do something on click
},
mouseenter: function() {
// do something on mouseenter
}
});  

4.3 区别传ref和传instance

图片 12 1 //
bind instance or reference 2 #include <functional> 3 #include
<iostream> 4 #include <string> 5 #include <vector> 6
#include <algorithm> 7 #include “boost/bind.hpp” 8 class tracer
9 { 10 public: 11 tracer() { std::cout << “tracer::tracer()\n”; }
12 tracer(const tracer& other) { std::cout <<
“tracer::tracer(const tracer& other)\n”; } 13 tracer& operator=(const
tracer& other) 14 { std::cout << “tracer& tracer::operator=(const
tracer& other)\n”; return *this; } 15 ~tracer() { std::cout <<
“tracer::~tracer()\n”; 16 } 17 void print(const std::string& s) const
18 { std::cout << s << ‘\n’; } 19 }; 20 21 void main() 22 {
23 tracer t; 24 boost::bind(&tracer::print,t,_1)(std::string(“I’m
called on a copy of t\n”)); 25 tracer t1; 26
boost::bind(&tracer::print,boost::ref(t1),_1)( std::string(“I’m called
directly on t\n”)); 27 28 } View
Code

5.bind的应用场景

从bind()方法的语法结构中可以看到,还有一个可选的data参数可供使用,此参数可以作为event.data属性值,传递给事件对象的额外数据对象。

2.任何作为type参数的字符串都是合法的;如果一个字符串不是原生的JavaScript事件名,那么这个事件处理函数会绑定到一个自定义事件上。这些自定义事件绝对不会由浏览器触发,但可以通过使用.trigger()或者.triggerHandler()在其他代码中手动触发。

2.任何作为type参数的字符串都是合法的;如果一个字符串不是原生的JavaScript事件名,那么这个事件处理函数会绑定到一个自定义事件上。这些自定义事件绝对不会由浏览器触发,但可以通过使用.trigger()或者.triggerHandler()在其他代码中手动触发。

5.bind的应用场景

5.1 绑定普通函数

  bind可以绑定普通函数,包括函数函数指针,假设我么有如下的函数定义:

图片 13图片 14

1 int f(int a,int b){return a+b;}   //二元函数
2 int g(int a,int b,int c) {return a+b+c;} //三元函数
3 typedef int (*f_type)(int,int);      //函数指针定义
4 typedef int (*g_type)(int,int,int); //函数指针定义

View Code

  那么,bind(f,1,2)
将返回一个无参调用函数对象,等价于f(1,2),bind(q,1,2,3)同样返回一个无参调用的函数对象,等价于
g(1,2,3)。这两个绑定表达式没有使用占位符,而是给出了全部的具体参数,代码:

1 cout<<bind(f,1,2)()<<endl;
2 cout<<bind(g,1,2,3)()<<endl;

  相当于:

1 cout<<f(1,2)<<endl;
2 cout<<g(1,2,3)<<endl; 

  使用占位符bind可以有更多的变化,这才是它真正应该做的工作,下面列出了一些占位符的用法:

图片 15图片 16

1 bind(f,_1,9)(x);  //f(x,9),相当于bind2nd(f,9)
2 bind(f,_1,_2)(x,y); //f(x,y)
3 bind(f,_2,_1)(x,y); //f(y,x)
4 bind(f,_1,_1)(x,y); //f(x,x),y参数被忽略
5 bind(g,_1,8,_2)(x,y) //g(x,8,y)
6 bind(g,_3,_2_2)(x,y,z) //g(z,y,y),x参数被忽略

View Code

  注意:必须绑定表达式中提供函数要求所有参数,无论是真实参数还是占位符均可以占位符可以出现也可以不出现,出现的顺序数量没有限定,但不能使用超过函数参数数量占位符,比如在绑定f是不能用_3,在绑定g时不能使用_4,也不能写bind(f,_1,_2,_2),这样的形式会导致编译错误。bind完全可以代替标准库中的bind1st和bind2nd,使用bind(f,N,_1)和bind(f,_1,N)。要注意的是它们均使用了一个占位符,bind1st把第一个参数用固定值代替,bind2nd把第二个参数用固定值代替。bind也可以绑定函数指针,用法相同,例如:

图片 17图片 18

1 f_type pf = f;
2 g_type pg = g;
3 int x =1,y=2,z=3;
4 cout<<bind(pf,_1,9)(x)<<endl; //(*pf(x,9))
5 cout<<bind(pg,_3,_2,_2)(x,y,z)<<endl; //(*pg)(z,y,y)

View Code

实例如下:

3.如果type参数的字符串中包含一个点(.)字符,那么这个事件就看做是有命名空间的了。这个点字符就用来分隔事件和他的命名空间。如:

3.如果type参数的字符串中包含一个点(.)字符,那么这个事件就看做是有命名空间的了。这个点字符就用来分隔事件和他的命名空间。如:

5.1 绑定普通函数

  bind可以绑定普通函数,包括函数函数指针,假设我么有如下的函数定义:

图片 191 int
f(int a,int b){return a+b;} //二元函数 2 int g(int a,int b,int c)
{return a+b+c;} //三元函数 3 typedef int (*f_type)(int,int);
//函数指针定义 4 typedef int (*g_type)(int,int,int); //函数指针定义
View Code

  那么,bind(f,1,2)
将返回一个无参调用函数对象,等价于f(1,2),bind(q,1,2,3)同样返回一个无参调用的函数对象,等价于
g(1,2,3)。这两个绑定表达式没有使用占位符,而是给出了全部的具体参数,代码:

1 cout<<bind(f,1,2)()<<endl;
2 cout<<bind(g,1,2,3)()<<endl;

  相当于:

1 cout<<f(1,2)<<endl;
2 cout<<g(1,2,3)<<endl; 

  使用占位符bind可以有更多的变化,这才是它真正应该做的工作,下面列出了一些占位符的用法:

图片 201
bind(f,_1,9)(x); //f(x,9),相当于bind2nd(f,9) 2 bind(f,_1,_2)(x,y);
//f(x,y) 3 bind(f,_2,_1)(x,y); //f(y,x) 4 bind(f,_1,_1)(x,y);
//f(x,x),y参数被忽略 5 bind(g,_1,8,_2)(x,y) //g(x,8,y) 6
bind(g,_3,_2_2)(x,y,z) //g(z,y,y),x参数被忽略 View Code

  注意:必须绑定表达式中提供函数要求所有参数,无论是真实参数还是占位符均可以占位符可以出现也可以不出现,出现的顺序数量没有限定,但不能使用超过函数参数数量占位符,比如在绑定f是不能用_3,在绑定g时不能使用_4,也不能写bind(f,_1,_2,_2),这样的形式会导致编译错误。bind完全可以代替标准库中的bind1st和bind2nd,使用bind(f,N,_1)和bind(f,_1,N)。要注意的是它们均使用了一个占位符,bind1st把第一个参数用固定值代替,bind2nd把第二个参数用固定值代替。bind也可以绑定函数指针,用法相同,例如:

图片 211 f_type
pf = f; 2 g_type pg = g; 3 int x =1,y=2,z=3; 4
cout<<bind(pf,_1,9)(x)<<endl; //(*pf(x,9)) 5
cout<<bind(pg,_3,_2,_2)(x,y,z)<<endl; //(*pg)(z,y,y)
View Code

5.2 bind绑定成员函数

  类的成员函数不同于普通的函数,因为成员函数指针不能直接调用operator(),它必须绑定到一个对象指针,然后才能得到this指针进而调用成员函数。因此bind需要 “牺牲”一个占位符,要求提供一个类的实例引用或者指针,通过对象作为第一个参数来调用成员函数,即:

1 bind(&X::func,x,_1,_2,…)

  这意味着使用成员函数时只能最多绑定8个参数。例如,有一个类demo

1 struct demo
2 {
3     int f(int a,int b){return a+b;}
4 };

  那么,下面的bind表达式都是成立的:

图片 22图片 23

1 demo a,&ra = a;    //类的实例对象和引用
2 demo * p = & a;     //指针
3 cout<<bind(&demo::f,a,_1,20)(10)<<endl;
4 cout<<bind(&demo::f,ra,_2,_1)(10,20)<<endl;
5 cout<<bind(&demo::f,p,_1,_2)(10,20)<<endl;

View Code

  注意:我们必须成员函数前面加上取地址的操作符&,表明这是一个成员函数指针,否则会无法编译通过,这是与绑定函数的一个小小的不同。bind同样支持绑定虚拟成员函数,用法与非虚函数相同,虚函数的行为将由实际调用发生时的实例来决定。

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>脚本之家</title>
<style type="text/css">
div{
 width:150px;
 height:40px;
 background-color:blue;
}
</style>
<script type="text/javascript" src="mytest/jQuery/jquery-1.8.3.js"></script>
<script type="text/javascript">
$(document).ready(function(){
 var newtext="脚本之家";
 $("#bt").bind("click",{"mytext":newtext},function(e){
  $("div").text(e.data.mytext);
 }) 
})
</script>
</head>
<body>
<div>您好</div>
<input type="button" id="bt" value="点击测试代码" />
</body>
</html>

$obj.bind(‘click.name’, handler) 那么字符串中的 click
是事件类型,而字符串 name 就是命名空间。

$obj.bind(‘click.name’, handler) 那么字符串中的 click
是事件类型,而字符串 name 就是命名空间。

5.2 bind绑定成员函数

  类的成员函数不同于普通的函数,因为成员函数指针不能直接调用operator(),它必须绑定到一个对象指针,然后才能得到this指针进而调用成员函数。因此bind需要
“牺牲”一个占位符
,要求提供一个类的实例引用或者指针,通过对象作为第一个参数来调用成员函数,即:

1 bind(&X::func,x,_1,_2,…)

  这意味着使用成员函数时只能最多绑定8个参数。例如,有一个类demo

1 struct demo
2 {
3     int f(int a,int b){return a+b;}
4 };

  那么,下面的bind表达式都是成立的:

图片 241 demo
a,&ra = a; //类的实例对象和引用 2 demo * p = & a; //指针 3
cout<<bind(&demo::f,a,_1,20)(10)<<endl; 4
cout<<bind(&demo::f,ra,_2,_1)(10,20)<<endl; 5
cout<<bind(&demo::f,p,_1,_2)(10,20)<<endl; View Code

  注意:我们必须成员函数前面加上取地址的操作符&,表明这是一个成员函数指针,否则会无法编译通过,这是与绑定函数的一个小小的不同。bind同样支持绑定虚拟成员函数,用法与非虚函数相同,虚函数的行为将由实际调用发生时的实例来决定。

5.3 bind绑定成员变量

  bind的另一个对类的操作是它可以绑定public成员变量,用法与绑定成员函数类似,只需要把成员变量名像一个成员函数一样去使用。例如:

1 vector<point> v(10);
2 vector<int> v2(10);
3 transform(v.begin(),v.end(),v2.begin(),bind(&point::x,_1));
4 BOOST_FOREACH(int x,v2) cout<<x<<“,”;

  代码中的bind(&point::x,_1)取出point对象的成员变量x,transform算法调用bind表达式操作容器v,逐个把成员变量填入到v2中。看到这里感到有点困惑,有点难以理解:bind返回的是一个函数对象,该对象对“()”进行了重载,在transform调用该重载函数应该是将v中的每一个成员变量作为参数传进去,从而取出每一个元素的x变量。

  使用bind可以实现SGISTL/STLport中的非标准函数适配器select1st和select2nd的功能,直接选择出pair对象first和second成员,例如:

1 typedef pair<int,string> pair_t;
2 pair_t p(123,”string”);
3 cout<<bind(&pair_t::first,p)()<<endl;
4 cout<<bind(&pair_t::second,p)()<<endl;

以上代码利用data参数为事件处函数的事件对象提供额外的数据进行处理,同样达到了第一个实例的效果。

行吧,就这点内容,下班回家了。这个月总结一篇jQuery开发的模式吧,一定好好准备准备。最后,希望这篇文章能给你有所帮助。

行吧,就这点内容,下班回家了。这个月总结一篇jQuery开发的模式吧,一定好好准备准备。最后,希望这篇文章能给你有所帮助。

5.3 bind绑定成员变量

  bind的另一个对类的操作是它可以绑定public成员变量,用法与绑定成员函数类似,只需要把成员变量名像一个成员函数一样去使用。例如:

1 vector<point> v(10);
2 vector<int> v2(10);
3 transform(v.begin(),v.end(),v2.begin(),bind(&point::x,_1));
4 BOOST_FOREACH(int x,v2) cout<<x<<“,”;

  代码中的bind(&point::x,_1)取出point对象的成员变量x,transform算法调用bind表达式操作容器v,逐个把成员变量填入到v2中。看到这里感到有点困惑,有点难以理解:bind返回的是一个函数对象,该对象对“()”进行了重载,在transform调用该重载函数应该是将v中的每一个成员变量作为参数传进去,从而取出每一个元素的x变量。

  使用bind可以实现SGISTL/STLport中的非标准函数适配器select1st和select2nd的功能,直接选择出pair对象first和second成员,例如:

1 typedef pair<int,string> pair_t;
2 pair_t p(123,”string”);
3 cout<<bind(&pair_t::first,p)()<<endl;
4 cout<<bind(&pair_t::second,p)()<<endl;

5.4 绑定函数对象

  bind不仅能够绑定函数和函数指针,也能够绑定任意的函数对象,包括标准库中预定义的函数对象。如果函数对象有内部类型定义result_type,那么bind可以自动推导返回值类型,用法与普通函数一样。但如果函数对象没有定义result_type,则需要在绑定形式上做一点改动,用模板参数指明返回类型,像这样:

1 bind<result_type>(Functor,…);

  标准库和Boost库中的大部分函数都具有result_type定义,因此不需要特别的形式就可以直接使用bind,例如:

1 bind(std::greater<int>(),_1,10);  //检查 x>10
2 bind(plus<int>(),_1,_2); //执行 x+y
3 bind(modulus<int>(),_1,3), //执行 x%3

  对于自定义的函数对象,如果没有result_type类型定义,例如:

1 struct f
2 {
3     int operator() (int a,int b) {return a +b;}
4 };

  那么我们必须指明

1 bind<int> (f(),_1,_2)(10,20)<<endl;

  这种写法所烧会有些不方便,因此,在编写自己的函数对象时,最好遵循规范为它们增加内部typedef
result_type
,这将使函数对象与其他的标准库和Boost库组件配合工作。

绑定多个事件:

您可能感兴趣的文章:

  • JQuery中绑定事件(bind())和移除事件(unbind())
  • jQuery中unbind()方法用法实例
  • jQuery中bind()方法用法实例
  • jquery
    bind(click)传参让列表中每行绑定一个事件
  • jquery中的常用事件bind、hover、toggle等示例介绍
  • Jquery之Bind方法参数传递与接收的三种方法
  • jQuery中bind与live的用法及区别小结
  • jQuery中bind,live,delegate与one方法的用法及区别解析
  • 深入理解jQuery中live与bind方法的区别
  • JQuery中Bind()事件用法分析

$(window).bind(‘load.jcarousel’, function() { windowLoaded = true;
}…

5.4 绑定函数对象

  bind不仅能够绑定函数和函数指针,也能够绑定任意的函数对象,包括标准库中预定义的函数对象。如果函数对象有内部类型定义result_type,那么bind可以自动推导返回值类型,用法与普通函数一样。但如果函数对象没有定义result_type,则需要在绑定形式上做一点改动,用模板参数指明返回类型,像这样:

1 bind<result_type>(Functor,…);

  标准库和Boost库中的大部分函数都具有result_type定义,因此不需要特别的形式就可以直接使用bind,例如:

1 bind(std::greater<int>(),_1,10);  //检查 x>10
2 bind(plus<int>(),_1,_2); //执行 x+y
3 bind(modulus<int>(),_1,3), //执行 x%3

  对于自定义的函数对象,如果没有result_type类型定义,例如:

1 struct f
2 {
3     int operator() (int a,int b) {return a +b;}
4 };

  那么我们必须指明

1 bind<int> (f(),_1,_2)(10,20)<<endl;

  这种写法所烧会有些不方便,因此,在编写自己的函数对象时,最好遵循规范为它们增加内部typedef
result_type
,这将使函数对象与其他的标准库和Boost库组件配合工作。

5.5 使用ref库

  bind采用拷贝的方式保存绑定对象参数,这意味着绑定表达式中的每一个变量都会有一份拷贝,如果函数对象或值参数很大、拷贝代价很高,或者无法拷贝,那么bind的使用就会受到限制。因此bind库可以搭配ref库使用,ref库包装了对象的引用,可以让bind存储对象引用的拷贝,从而降低了拷贝的代价。但这也带来了一个隐患,因为有时候bind的调用可能会延后很久,程序员必须保证bind被调用时引用是有效的。如果调用是引用的变量或者函数对象你被销毁了,那么将会发生未定义行为。ref配合bind用法的代码如下:

1 int x = 10;
2 cout<<bind(g,_1,cref(x),ref(x))(10)<<endl;
3 f af;
4 cout<<bind<int>(ref(af),_1,_2)(10,20)<<endl;

  下面的代码则因为引用失效,引发未定义行为:

图片 25图片 26

 1 int x = 10;
 2 BOOST_AUTO(r,ref(x));
 3 {
 4     int * y = new int(20);
 5     r = ref(*y);
 6     cout<<r<<endl;
 7     cout<<bind(g,r,1,1)()<<endl;
 8     delete y;
 9 }
10 cout<<bind(g,r,1,1)()<<endl;

View Code

可以使用链式编程的方式为匹配元素绑定多个事件。代码如下:

5.5 使用ref库

  bind采用拷贝的方式保存绑定对象参数,这意味着绑定表达式中的每一个变量都会有一份拷贝,如果函数对象或值参数很大、拷贝代价很高,或者无法拷贝,那么bind的使用就会受到限制。因此bind库可以搭配ref库使用,ref库包装了对象的引用,可以让bind存储对象引用的拷贝,从而降低了拷贝的代价。但这也带来了一个隐患,因为有时候bind的调用可能会延后很久,程序员必须保证bind被调用时引用是有效的。如果调用是引用的变量或者函数对象你被销毁了,那么将会发生未定义行为。ref配合bind用法的代码如下:

1 int x = 10;
2 cout<<bind(g,_1,cref(x),ref(x))(10)<<endl;
3 f af;
4 cout<<bind<int>(ref(af),_1,_2)(10,20)<<endl;

  下面的代码则因为引用失效,引发未定义行为:

图片 27 1 int x
= 10; 2 BOOST_AUTO(r,ref(x)); 3 { 4 int * y = new int(20); 5 r =
ref(*y); 6 cout<<r<<endl; 7
cout<<bind(g,r,1,1)()<<endl; 8 delete y; 9 } 10
cout<<bind(g,r,1,1)()<<endl; View Code

5.6 存储bind表达式

  很多时候我们需要把写好的bind表达式存储起来,以便稍后再度使用,但bind表达式生成的对象类型声明非常复杂,通常无法写出正确的类型,因此可以使用typeof库的BOOST_AUTO宏来辅助我们,例如:

1 BOOST_AUTO(x,bind(greater<int>(),_1,_2));
2 cout<<x(10,20)<<endl;

  bind可以嵌套,一个bind表达式生成的函数对象可以被另一个bind再绑定,从而实现类似f(g(x))的形式,如果我们有f(x)和g(x)两个函数,那么f(g(x))的bind表达式就是:

1 bind(f,bind(g,_1))(x)

  使用bind的嵌套用法必须小心,它不太容易一次写对,也不太容易理解,超过两个以上的bind表达式通常只能被编译器读懂,必须配合良好的注释才能够使用bind嵌套用法。

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>脚本之家</title>
<style type="text/css">
div{
 width:150px;
 height:40px;
 background-color:blue;
}
</style>
<script type="text/javascript" src="mytest/jQuery/jquery-1.8.3.js"></script>
<script type="text/javascript">
$(document).ready(function(){
 var newtext="脚本之家";
 $("#bt").bind("click",{"mytext":newtext},function(e){
  $("div").text(e.data.mytext);
 }).bind("mouseout",function(){
  alert("欢迎下次光临");
 }) 
})
</script>
</head>
<body>
<div>您好</div>
<input type="button" id="bt" value="点击测试代码" />
</body>
</html>

5.6 存储bind表达式

  很多时候我们需要把写好的bind表达式存储起来,以便稍后再度使用,但bind表达式生成的对象类型声明非常复杂,通常无法写出正确的类型,因此可以使用typeof库的BOOST_AUTO宏来辅助我们,例如:

1 BOOST_AUTO(x,bind(greater<int>(),_1,_2));
2 cout<<x(10,20)<<endl;

  bind可以嵌套,一个bind表达式生成的函数对象可以被另一个bind再绑定,从而实现类似f(g(x))的形式,如果我们有f(x)和g(x)两个函数,那么f(g(x))的bind表达式就是:

1 bind(f,bind(g,_1))(x)

  使用bind的嵌套用法必须小心,它不太容易一次写对,也不太容易理解,超过两个以上的bind表达式通常只能被编译器读懂,必须配合良好的注释才能够使用bind嵌套用法。

5.7 绑定非标准函数

  bind可以适配任何一种C++中的函数,但标准形式bind(f,…)不是适用所用的情况,有些非标准函数无法制动推导出返回值类型,典型的就是C中的可变参数函数printf()。必须用bind<int>(printf,…)(…),例如:

1 bind<int>(printf,”%d+%d=%d\n”,_1,_1,_2)(6,7);

  bind的标准形式不能支持使用了不同的调用方式,如:__stdcall__fastcallextern”C”的函数,通常bind把他们看做函数对象,需要显示的指定bind的返回值类型才能绑定。

 

原文链接:

为按钮绑定了两个事件处理函数,当点击按钮的时候能够重新设置div中的文本,当鼠标离开按钮的时候,会弹出文本框。

5.7 绑定非标准函数

  bind可以适配任何一种C++中的函数,但标准形式bind(f,…)不是适用所用的情况,有些非标准函数无法制动推导出返回值类型,典型的就是C中的可变参数函数printf()。必须用bind<int>(printf,…)(…),例如:

1 bind<int>(printf,”%d+%d=%d\n”,_1,_1,_2)(6,7);

  bind的标准形式不能支持使用了不同的调用方式,如:__stdcall__fastcallextern”C”的函数,通常bind把他们看做函数对象,需要显示的指定bind的返回值类型才能绑定。

 

原文链接:

1.Boost::bind
在STL中,我们经常需要使用bind1st,bind2st函数绑定器和fun_ptr,mem_fun等函数适配器,这些函数绑…

使浏览器默认事件失效

例如点击链接跳转到一个指定的地址和点击提交按钮提交表单都是浏览器默认的事件。但是在实际操作过程中,这些默认事件并非我们想要的操作,例如早表单验证没有通过的时候,就不想提交表单。这个时候就需要阻止浏览器默认事件的发生。

代码实例如下:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>脚本之家</title>
<script type="text/javascript" src="mytest/jQuery/jquery-1.8.3.js"></script>
<script type="text/javascript">
$(document).ready(function(){
 $(":submit").bind("click",function(){
  if($("#username").val()=="")
  {
   alert("用户名不能为空!");
   $("#username").focus();
   return false;
  }
  if($("#pw").val()=="")
  {
   alert("密码不能为空!");
   $("#pw").focus();
   return false;
  }
 })
})
</script>
</head>
<body>
<form action="" name="myform">
<ul>
 <li>用户名:<input type="text" id="username" /></li>
 <li>密码:<input type="password" id="pw" /></li>
 <li><button>提交表单</button></li>
</ul>
</form>
</body>
</html>

以上所述就是本文的全部内容了,希望大家能够喜欢。

您可能感兴趣的文章:

  • JQuery中Bind()事件用法分析
  • jQuery中bind()方法用法实例
  • jQuery中unbind()方法用法实例
  • jQuery
    unbind()方法实例详解
  • jQuery使用技巧简单汇总
  • jQuery
    on()方法使用技巧详解
  • jQuery
    常见开发使用技巧总结
  • Jquery使用小技巧汇总
  • 更高效的使用JQuery
    这里总结了8个小技巧
  • jquery中关于bind()方法的使用技巧分享

相关文章