boost bind初步探究 (三)

2014-11-24 00:59:37 · 作者: · 浏览: 11
::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_]);
}
....

尽管有多种不同的重载,但是基本形式就是这样的。
最后一个参数"int"我想没有直接的意义,可能是为了重载时用于区分不同的重载函数使用的。


unwrap的作用这里可以忽略。你可以认为就是直接调用f。


下面有两个不同寻常的语句:[html] view plaincopyprint a[base_type::a1_], a[base_type::a2_]

a[base_type::a1_], a[base_type::a2_]a是一个listN对象,这两句究竟是什么意思呢?


下面,我们用两个例子分别说明,
例子1
bind(f, 1, 2)(); //f(1,2)下面,我们将参数代入:这种情况下,我们得到的bind_t对象,实际上是
[cpp]
bind_t >
//l_的类型和值
list2 = [ base_type::a1_ = 1, base_type::a2_ = 2]

bind_t >
//l_的类型和值
list2 = [ base_type::a1_ = 1, base_type::a2_ = 2]
而bind(f, 1, 2) (); 中最后一个括号,调用了bind_t的operator () (void) :
[cpp]
result_type operator()()
{
list0 a;
BOOST_BIND_RETURN l_(type(), f_, a, 0);
}

result_type operator()()
{
list0 a;
BOOST_BIND_RETURN l_(type(), f_, a, 0);
}
因此,a = list0。
在这种情况下,
[cpp] v
a[base_type::a1_] = =
a.operator[]((_bi::value) 1)
== 1;
a[base_type::a2_] ==
a.operator[](_bi::value) 2)
== 2;

a[base_type::a1_] = =
a.operator[]((_bi::value) 1)
== 1;
a[base_type::a2_] ==
a.operator[](_bi::value) 2)
== 2;其实listN里面的operator[](_bi::value)就是打酱油的,目的就是为了在语法上统一。


因此,bind(f, 1, 2) () === f(1,2)的调用。


例子2
bind(f, _2, _1)(x, y); // f(y, x)我们再把参数代入,这是,得到的bind_t对象就是
[html]
bind_t, boost::arg<1> > >
//l_的类型和值是
list2,boost::arg<1> > = [ base_type::a1_ = _2, base_type::a2_ = _1]

bind_t, boost::arg<1> > >
//l_的类型和值是
list2,boost::arg<1> > = [ base_type::a1_ = _2, base_type::a2_ = _1]哈哈,看到了吧,list2的类型不一定要和F的参数类型一样的哦。


当调用bind(f, _2, _1)(x, y); 中bind_t::operator()(int, int) 的时候,即
[cpp]
template result_type operator()(A1 & a1, A2 & a2)
{
list2 a(a1, a2);
BOOST_BIND_RETURN l_(type(), f_, a, 0);
}

template result_type operator()(A1 & a1, A2 & a2)
{
list2 a(a1, a2);
BOOST_BIND_RETURN l_(type(), f_, a, 0);
}
此时,a的类型和值是
[cpp] v
list2 = [ base_type::a1_= x, base_type::a2_ = y]

list2 = [ base_type::a1_= x, base_type::a2_ = y]这种情况下,
[html]
a[l_.base_type::a1_] ==
a [ _2 ] ==
a.operator[] ( (boost::arg<2>&)_2) ==
a.base_type::a2_ ==
y;

a[l_.base_type::a2_] ==
a [ _1 ] ==
a.operator[] ( (boost::arg<1>&)_1) ==
a.base_type::a1_ ==
x;

a[l_.base_type::a1_] ==
a [ _2 ] ==
a.operator[] ( (boost::arg<2>&)_2) ==
a.base_type::a2_ ==
y;

a[l_.base_type::a2_] ==
a [ _1 ] ==
a.operator[] ( (boost::arg<1>&)_1) ==
a.base_type::a1_ ==
x;

即 bind(f, _2, _1)(x, y) === f(y, x);


关于_1,_2,_3,...._9
现在,我们要看看,到底 boost::arg<1>, boost::arg<2> ... boost::arg<9>是什么了。
[cpp]
template< int I > struct arg
{
arg()
{
}

template< class T > arg( T const & /* t */ )
{
// static assert I == is_placeholder::value
typedef char T_must_be_placeholder[ I == is_placeholder::value 1: -1 ];
}
};

template< int I > struct arg
{
arg()
{
}

template< class T > arg( T const & /* t */ )
{
// static assert I == is_placeholder::value
typedef char T_must_be_placeholder[ I == is_placeholder::value 1: -1 ];
}
};

呵呵,什么都没有!的确,什么都没有,因为它是placheholder嘛! 它只要表明自己的类型就可以了。这是为什么在 listN的operator[] 中,boost::arg 没有定义形惨了。


第二个带有 T const & 参数的构造函数是什么?看起来很奇怪,其实,它是拷贝构造函数。


看看is_placeholder的定义吧:
[cpp]
template< int I > struct is_placeholder< arg >
{
enum _vt { value = I };
};

template< int I > struct is_placeholder< arg >
{
enum _vt { value = I };
};

它的作用,是防止错误的参考构造。
假如,你这样定义:
[cpp]
boost::arg<2> arg2(_1);

boost::arg<2> arg2(_1);模板展开后,将是这样的
[cpp]
struct arg <2>
{
.....
arg( arg<1> const & /* t */ )
{