我想转换这个简单的代码:
void setZComp(Imath::V3f& pt)
{
pt.z = 0.0;
}
int myfunc()
{
...
std::vector<Imath::V3f> vec(5,Imath::V3f(1.0,1.0,1.0));
std::for_each(vec.begin(),vec.end(),boost::bind(&setZComp,_1));
...
}
之类的东西,为了不在外面声明setZComp,而是某种内联声明
int myfunc()
{
...
boost::function<double(Imath::V3f&)> f = (boost::lambda::_1 ->* &Imath::V3f::z = 0.0) ;
std::for_each(vec.begin(),vec.end(),boost::bind(&f,_1));
...
}
我对Boost Bind和Lambda很新,我不知道这是否可以通过某种方式完成。显然上面的代码不起作用。
答案 0 :(得分:2)
你是否正在使用大锤打破坚果?有时,我认为使用普通的for循环并自己明确设置变量更简单。这使代码更容易阅读和维护。
typedef std::vector<Imath::V3f> V3fVector;
V3fVector vec(5,Imath::V3f(1.0,1.0,1.0));
for (V3fVector::iterator i = vec.begin(), iEnd = vec.end(); iEnd != i; ++i)
i->z = 0.0;
尽管boost绑定很有用,但它也是一种语法混乱,使得简单的代码无法读取。
答案 1 :(得分:2)
如果你不能使用C ++ 11 lambda,那么你可以使用boost::lambda::bind
所以在你的情况下,如下所示:
boost::lambda::bind(&Imath::V3f::z, boost::lambda::_1) = 0.0
一个完整的例子,因为我不知道你的内部:
struct S
{
S():i(0){};
int i;
};
int main()
{
std::vector<S> vec;
vec.push_back(S());
std::for_each(vec.begin(), vec.end(), boost::lambda::bind(&S::i, boost::lambda::_1) = 5);
std::cout << vec.front().i << std::endl; // outputs 5
return 0
}
答案 2 :(得分:1)
你也可以考虑看一下boost :: phoenix。我认为这是一个比lambda库更完整的c ++函数式编程实现。
答案 3 :(得分:1)
如Member variables as targets部分所述:
指向成员变量的指针实际上不是函数,但[
boost::lambda::bind
]函数的第一个参数仍然是指向成员变量的指针。调用这样的绑定表达式将返回对数据成员的引用。
因此,要构建一个访问z
成员的lambda表达式,您可以使用:
boost::lambda::bind(&Imath::V3f::z, boost::lambda::_1)
返回的对象本身可以在其他表达式中使用。例如,
boost::lambda::bind(&Imath::V3f::z, boost::lambda::_1) = 0.0
表示“获取double
引用第一个参数的z
成员(类型Imath::V3f&
)并赋值0.0”。
然后,您可以将此lambda与Boost.Function和std::for_each
:
boost::function<void(Imath::V3f&)> f = boost::lambda::bind(&Imath::V3f::z, boost::lambda::_1) = 0.0;
std::for_each(vec.begin(), vec.end(), f);
作为参考,这是一个完整的,可编译的例子:
#include <algorithm>
#include <cstdlib>
#include <iostream>
#include <vector>
#include <boost/function.hpp>
#include <boost/lambda/bind.hpp>
#include <boost/lambda/lambda.hpp>
namespace Imath
{
class V3f
{
public:
double x, y, z;
V3f(double x_, double y_, double z_)
: x(x_), y(y_), z(z_)
{
}
friend std::ostream& operator<<(std::ostream& os, const V3f& pt) {
return (os << '(' << pt.x << ", " << pt.y << ", " << pt.z << ')');
}
};
}
int main()
{
std::vector<Imath::V3f> vec(5, Imath::V3f(1.0, 1.0, 1.0));
boost::function<void(Imath::V3f&)> f = boost::lambda::bind(&Imath::V3f::z, boost::lambda::_1) = 0.0;
std::for_each(vec.begin(), vec.end(), f);
std::vector<Imath::V3f>::iterator it, end = vec.end();
for (it = vec.begin(); it != end; ++it) {
std::cout << *it << std::endl;
}
return EXIT_SUCCESS;
}
输出:
(1, 1, 0) (1, 1, 0) (1, 1, 0) (1, 1, 0) (1, 1, 0)
答案 4 :(得分:0)
如果您可以访问具有C ++ 11支持的最新版g++
或MSVC 2010,则可以执行以下操作:
int myfunc()
{
...
std::for_each(vec.begin(),vec.end(),[](Imath::V3f& pt){ pt.z = 0.0; });
...
}
答案 5 :(得分:0)
如果你想使用boost :: lambda,我有时会发现在包含lambda的行之前声明一个“指向成员的指针”变量更清晰,然后允许你使用 - &gt; *运算符而不是使用boost :: lambda :: bind。
然而,正如艾伦所指出的,这里的简单循环可能是最简单的解决方案。使用BOOST_FOREACH使其更简单。
这是mkaes示例实现的修改版本,它使用operator - &gt; *而不是bind,它还显示了如何使用BOOST_FOREACH作为替代。
#include <iostream>
#include <vector>
#include <boost/lambda/lambda.hpp>
#include <boost/foreach.hpp>
// I like to provide alternate names for the boost::lambda placeholders
boost::lambda::placeholder1_type& arg1 = boost::lambda::_1 ;
boost::lambda::placeholder2_type& arg2 = boost::lambda::_2 ;
boost::lambda::placeholder3_type& arg3 = boost::lambda::_3 ;
struct S
{
S():i(0){};
int i;
};
int main()
{
std::vector<S> vec;
vec.push_back(S());
// Define this pointer-to-member so we can
// use it in the lambda via the ->* operator
int S::* i = &S::i ;
std::for_each(vec.begin(), vec.end(), &arg1->*i = 5);
std::cout << vec.front().i << std::endl; // outputs 5
// Alternatively, just use a simple foreach loop
BOOST_FOREACH( S & s, vec )
{
s.i = 6 ;
}
std::cout << vec.front().i << std::endl; // outputs 6
return 0 ;
}