Допустим, у меня есть объект Car
, который также имеет член Engine
, и я хочу проверить свойства объекта, вызывая некоторые методы на Car
и некоторые методы на Engine
.Чтобы получить информацию в явном виде, я мог бы сделать
cout << "my car has " << mycar.GetEngine().NCylinders() << " cylinders" << endl;
cout << "my car has " << mycar.NWheels() << " wheels" << endl;
, все эти вызовы имеют форму 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;
}
, который хорошо выводит:
my car has: 12 cylinders
my car has: 4 wheels
Но вложенные связки могут стать уродливыми с более длинными цепочками или методами в середине, которые должны иметь фиксированные аргументы, и мне было интересно, могут ли бытьРешение, использующее лямбда-выражения, которое может привести к чему-то вроде
//pseudocode
carinfos["cylinders"] = (_1.GetEngine().NCylinder());
carinfos["wheels"] = (_1.GetNWheel());
Edit:
@ KennyTM и @Kerrek SB, предоставило отличные ответы, используя новые лямбда-выражения C ++ 11.Я пока не могу использовать C ++ 11, поэтому я был бы признателен за решения аналогичной краткости, использующие C ++ 03