假设我有一个Car也有Engine成员的对象,我想检查对象的属性,调用一些方法Car和一些方法Engine.为了明确地获取te信息,我可以做到
cout << "my car has " << mycar.GetEngine().NCylinders() << " cylinders" << endl;
cout << "my car has " << mycar.NWheels() << " wheels" << endl;
Run Code Online (Sandbox Code Playgroud)
所有这些电话都是这种形式mycar.<some method call chain here>.(您还可以假设它们都具有兼容的返回类型).我怎样才能有一个仿函数列表,以便我可以传递一个Car实例,它会相应地执行调用.
我<tr1/functional>使用嵌套绑定提出了一个解决方案.
#include <iostream>
#include <tr1/functional>
#include <map>
using namespace std;
using namespace std::tr1;
using namespace std::tr1::placeholders;
struct Engine{
int NCylinders() const {return 12;}
};
struct Car{
int NWheels() const {return 4;}
Engine GetEngine() const {return myEngine;}
private:
Engine myEngine;
};
int main(){
Car mycar;
map<string,function<double (const Car&)> > carinfos;
carinfos["cylinders"] = bind(&Engine::NCylinders,bind(&Car::GetEngine,_1));
carinfos["wheels"] = bind(&Car::NWheels,_1);
map<string,function<double (const Car&)> >::const_iterator info = carinfos.begin();
for(;info!=carinfos.end();++info){
cout << "my car has: " << (info->second)(mycar) << " " << info->first << endl;
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出很好:
my car has: 12 cylinders
my car has: 4 wheels
Run Code Online (Sandbox Code Playgroud)
但是嵌套的绑定可能会变得丑陋,中间有更长的链或方法,必须有固定的参数,我想知道是否可能有一个使用lambda表达式的解决方案,这可能导致像
//pseudocode
carinfos["cylinders"] = (_1.GetEngine().NCylinder());
carinfos["wheels"] = (_1.GetNWheel());
Run Code Online (Sandbox Code Playgroud)
编辑:
@KennyTM和@Kerrek SB使用新的C++ 11 lambda表达式提供了出色的答案.我还不能使用C++ 11,所以我很欣赏使用C++ 03的类似简洁的解决方案
以下,使用lambdas而不是绑定,看起来并不太糟糕:
typedef std::map<std::string, std::function<int(Car const &)>> visitor;
int main()
{
visitor v;
v["wheels"] = [](Car const & c) -> int { return c.NWheels(); };
v["cylinders"] = [](Car const & c) -> int { return c.GetEngine().NCylinders(); };
Car c;
for (auto it = v.cbegin(), end = v.cend(); it != end; ++it)
{
std::cout << "My car has " << it->second(c) << " " << it->first << ".\n";
}
}
Run Code Online (Sandbox Code Playgroud)
循环可以包含在visit(c, v);函数中.