关于 Boost.Lambda

王朝other·作者佚名  2006-01-10
宽屏版  字体: |||超大  

Boost.Lambda 的确是一个好东西,用来举例最多的恐怕就是这个了:

using namespace boost::lambda;

std::vector<int> v;

// init values

std::for_each(v.begin(), v.end(), std::cout << _1 << ' ');

精致、优雅、易于理解,下面是一个更漂亮的例子:

std::map<int, int> values;

// init values

std::for_each(values.begin(), values.end(),

std::cout << bind(&std::map<int,int>::value_type::first, _1) << '\t'

<< bind(&std::map<int,int>::value_type::second, _1) << '\n'

);

它将把一个 map 打印成表格形式,其中的 bind 是 boost::lambda::bind,而不是 boost::bind。

看起来都是那么的轻易,但是我在下面的代码上却遇到了麻烦:

std::map<int,int>::iterator iter =

bind(&std::map<int,int>::find, &values, _1)(boost::cref(1));

任我使尽浑身解数,它还是没能编译成功,要知道这种情况经常给出几公里长的出错信息,要从中了解问题的症结几乎不太可能。然而,下面这一句非常相似的却成功运行:

std::cout << bind(&std::map<int,int>::count, &values, _1)(boost::cref(1));

一个是 bind 到 find,一个是 bind 到 count ,它们有什么区别呢?看看 STL(VC7.1) 的实现就发现,find 有两个版本:const 和 mutable ,而 count 只有一个版本。

难道是 Boost.Lambda 在遇到 constness 重载的时候出了问题?验证一下:

class A

{

int i, j;

public:

int& I()

{ return i; }

const int& I()const

{ return i; }

int J()

{ return j; }

}a;

//.......

std::cout << bind(&A::I, _1)(a);

果然不假,上面的代码编译的时候给出类似的错误信息,而下面这一句则没有问题:

std::cout << bind(&A::J, _1)(a);

然而,如果换用 Boost.Bind ,则在两种情况下都可以正确运行,包括上面所说的 count 和 find 。不过,最妙的是只要拿掉

using namespace boost::lambda;

而改用

using namespace boost;

那么同样的代码无需修改就可以运行了。

我还没有仔细看 Boost.Lambda 的代码来确定到底发生了什么,但是 C++0x 标准并没有接纳 lambda,可能也和这些实现上的问题有关吧。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
© 2005- 王朝网络 版权所有