- 论坛徽章:
- 2
|
原帖由 bidongliang 于 2009-4-16 12:12 发表
没有问题吧, bind的返回值是一个函数对象,没有参数只是没有调用返回对象的operator ()而已.
楼上已经说得很清楚了, 因为楼主仅仅生成, 没有调用该函数对象。
再举几个例子:
设, R f(P1, P2, P3, ... , Pn)
bind(&f, a1, a2, _1, _2, ..., _n-2 ) 这个表达式,产生的是一个函数对象。
它的类型很难写出来, 一般会这样
—— 1. 立即使用之, 如:
R r1 = bind(&f, a1, a2, _1, _2, ..., _n-2 )( a3, a4, a5, ... , an);
R r2 = f(a1,a2, ... ,an ); // 上面的表达式效果同下面这个函数
assert( r1 == r2);
—— 2. 传递给范型算法, 如:
vecotr< int > v; // 填充v
// 打算使用 transform 给v的每个元素增加一个值
// 因为 transform 是这么写的
template < class InputIterator, class OutputIterator, class UnaryOperator >
OutputIterator transform ( InputIterator first1, InputIterator last1,
OutputIterator result, UnaryOperator op )
{
while (first1 != last1)
*result++ = op(*first1++);
return result;
}
内部调用了一个函数对象f, f必须可以接受单个参数, 该参数存在从*first的隐式转换。
如果直接使用 std::plus<int> 是不行的, 因为它接受2个参数。
template< typnename T >
struct std::plus : std::binary_function< T, T,T >
{
T operator()(const T& v1,const T& v2) const {
return v1 + v2;
}
};
所以需要bind来固定一个参数, 返回接受余下参数的函数对象。
如, bind(std::plus< int >, 1212, _1 ); 就固定了第1个参数 1212, 返回了接受余下(还剩一个参数)参数的函数对象)
那么, 如果立即调用 bind(std::plus< int >, 1212, _1 )( v[ i ] ) 就等于 std::plus< int >( 1212 , v[ i ] );
也就可以将产生的函数对象, 传递给transform
transform(v.begin(), v.end(), v.begin(), bind(std::plus< int >, 1212, _1 ) );
transform 会对每个 v[ i ] 调用 v[ i ] = f( v[ i ] ) 也就是 v[ i ] = 1212 + v[ i ];
btw: 做这个事情, lambda表达式更简洁。
——3 使用具名对象, 一般不会这么用。
因为bind出的函数对象的类型非常难以写出来。
我不知道怎么写 …… 我只知道std中的binder类怎么写 ……
比如 int plus( int x, int y ) { return x + y; }
std:: pointer_to_binary_function< int (*)(int,int) > p ( &plus );
std:: binder1st< std:: pointer_to_binary_function< int (*)(int,int) > > f( p, 1212 );
然后, transform(v.begin(), v.end(), v.begin(), f );
或者自己调用 v[ 0 ] = f( v[ 0 ] );
C++0x会改变auto关键字的含义, 会自动推测类型。 上面就可以写得舒服一些了。
auto p = std::ptr_fun(&plus);
auto f = std::bind1st( p, 1212 );
我们根本就不关心 p, f是什么类型, 只是想声明一个具名对象去引用它。
[ 本帖最后由 OwnWaterloo 于 2009-4-16 14:58 编辑 ] |
|