免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1804 | 回复: 6
打印 上一主题 下一主题

[C++] 语法难题N003 [复制链接]

论坛徽章:
223
2022北京冬奥会纪念版徽章
日期:2015-08-10 16:30:32操作系统版块每日发帖之星
日期:2016-05-10 19:22:58操作系统版块每日发帖之星
日期:2016-02-18 06:20:00操作系统版块每日发帖之星
日期:2016-03-01 06:20:00操作系统版块每日发帖之星
日期:2016-03-02 06:20:0015-16赛季CBA联赛之上海
日期:2019-09-20 12:29:3219周年集字徽章-周
日期:2019-10-01 20:47:4815-16赛季CBA联赛之八一
日期:2020-10-23 18:30:5320周年集字徽章-20	
日期:2020-10-28 14:14:2615-16赛季CBA联赛之广夏
日期:2023-02-25 16:26:26CU十四周年纪念徽章
日期:2023-04-13 12:23:10操作系统版块每日发帖之星
日期:2016-05-10 19:22:58
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-04-16 10:19 |只看该作者 |倒序浏览
20可用积分
关于boost/bind

int f(int a, int b){ return a+b;}

int i = 5;
bind(f, i, _1);   //L1
bind(f, ref(i), _1);
bind(f, cref(42), _1);


请问,L1代码有无语法问题?

[ 本帖最后由 action08 于 2009-4-16 11:37 编辑 ]

最佳答案

查看完整内容

楼上已经说得很清楚了, 因为楼主仅仅生成, 没有调用该函数对象。再举几个例子:设, 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. 传递给范型算 ...

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
2 [报告]
发表于 2009-04-16 10:19 |只看该作者
原帖由 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 编辑 ]

论坛徽章:
223
2022北京冬奥会纪念版徽章
日期:2015-08-10 16:30:32操作系统版块每日发帖之星
日期:2016-05-10 19:22:58操作系统版块每日发帖之星
日期:2016-02-18 06:20:00操作系统版块每日发帖之星
日期:2016-03-01 06:20:00操作系统版块每日发帖之星
日期:2016-03-02 06:20:0015-16赛季CBA联赛之上海
日期:2019-09-20 12:29:3219周年集字徽章-周
日期:2019-10-01 20:47:4815-16赛季CBA联赛之八一
日期:2020-10-23 18:30:5320周年集字徽章-20	
日期:2020-10-28 14:14:2615-16赛季CBA联赛之广夏
日期:2023-02-25 16:26:26CU十四周年纪念徽章
日期:2023-04-13 12:23:10操作系统版块每日发帖之星
日期:2016-05-10 19:22:58
3 [报告]
发表于 2009-04-16 10:57 |只看该作者
没有人会吗?我头已经被搞大老


L1等价于
f(5,_1);可见鬼的_1后面没得参数..

[ 本帖最后由 action08 于 2009-4-16 10:59 编辑 ]

论坛徽章:
0
4 [报告]
发表于 2009-04-16 12:12 |只看该作者
没有问题吧, bind的返回值是一个函数对象,没有参数只是没有调用返回对象的operator ()而已.

论坛徽章:
223
2022北京冬奥会纪念版徽章
日期:2015-08-10 16:30:32操作系统版块每日发帖之星
日期:2016-05-10 19:22:58操作系统版块每日发帖之星
日期:2016-02-18 06:20:00操作系统版块每日发帖之星
日期:2016-03-01 06:20:00操作系统版块每日发帖之星
日期:2016-03-02 06:20:0015-16赛季CBA联赛之上海
日期:2019-09-20 12:29:3219周年集字徽章-周
日期:2019-10-01 20:47:4815-16赛季CBA联赛之八一
日期:2020-10-23 18:30:5320周年集字徽章-20	
日期:2020-10-28 14:14:2615-16赛季CBA联赛之广夏
日期:2023-02-25 16:26:26CU十四周年纪念徽章
日期:2023-04-13 12:23:10操作系统版块每日发帖之星
日期:2016-05-10 19:22:58
5 [报告]
发表于 2009-04-16 13:07 |只看该作者

回复 #3 bidongliang 的帖子

换句话说,这段代码将不执行函数操作?

但是语法是正确的,那再看一条见鬼的

typedef void (*pf)(int);

std::vector<pf> v;

std::for_each(v.begin(), v.end(), bind(apply<void>(), _1, 5));



----
又出现了同样的占位符,怎么理解呢?

[ 本帖最后由 action08 于 2009-4-16 15:57 编辑 ]

论坛徽章:
0
6 [报告]
发表于 2009-04-16 15:26 |只看该作者
滑铁卢又出山了~~~

论坛徽章:
223
2022北京冬奥会纪念版徽章
日期:2015-08-10 16:30:32操作系统版块每日发帖之星
日期:2016-05-10 19:22:58操作系统版块每日发帖之星
日期:2016-02-18 06:20:00操作系统版块每日发帖之星
日期:2016-03-01 06:20:00操作系统版块每日发帖之星
日期:2016-03-02 06:20:0015-16赛季CBA联赛之上海
日期:2019-09-20 12:29:3219周年集字徽章-周
日期:2019-10-01 20:47:4815-16赛季CBA联赛之八一
日期:2020-10-23 18:30:5320周年集字徽章-20	
日期:2020-10-28 14:14:2615-16赛季CBA联赛之广夏
日期:2023-02-25 16:26:26CU十四周年纪念徽章
日期:2023-04-13 12:23:10操作系统版块每日发帖之星
日期:2016-05-10 19:22:58
7 [报告]
发表于 2009-04-16 16:00 |只看该作者
C++真是够抽象,
表达式,
函数,
指针,


消化中~~~

[ 本帖最后由 action08 于 2009-4-16 16:06 编辑 ]
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP