#include <algorithm>
#include <iostream>
#include <list>
template <typename T, typename MPtr>
auto arrow(T* obj, MPtr mptr)
{
return obj->*mptr;
}
template <typename T, typename MPtr, typename ... MPtrs>
auto arrow(T* obj, MPtr mptr, MPtrs... mptrs)
{
return arrow(obj->*mptr, mptrs...);
}
template <typename Container, typename T, typename... DataPtrs>
auto searchByDataMember (const Container& container, const T& t, DataPtrs... ptrs)
{
return std::find_if(std::begin(container), std::end(container),
[&](const auto&e) {
return arrow(e, ptrs...) == t;
});
}
struct Thing {
int ID, value;
std::string name;
Thing (int i, int v, const std::string& n) : ID(i), value(v), name(n) {}
};
struct Object {
int rank;
Thing* thing;
Object (int r, Thing* t) : rank(r), thing(t) {}
};
int main() {
Thing thing1(5, 6, "Sam");
Object o1(8, &thing1);
Thing thing2(11, 7, "Mark");
Object o2(8, &thing2);
Thing thing3(9, 12, "Rob");
Object o3(8, &thing3);
Thing thing4(2, 11, "Tom");
Object o4(8, &thing4);
std::list<Object*> objects{&o1, &o2, &o3, &o4};
const auto it = searchByDataMember (objects, 11, &Object::thing, &Thing::value);
std::cout << (*it)->thing->name << '\n'; // Tom (the desired output)
}
I2luY2x1ZGUgPGFsZ29yaXRobT4KI2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8bGlzdD4KCnRlbXBsYXRlIDx0eXBlbmFtZSBULCB0eXBlbmFtZSBNUHRyPgphdXRvIGFycm93KFQqIG9iaiwgTVB0ciBtcHRyKQp7CiAgICByZXR1cm4gb2JqLT4qbXB0cjsKfQoKdGVtcGxhdGUgPHR5cGVuYW1lIFQsIHR5cGVuYW1lIE1QdHIsIHR5cGVuYW1lIC4uLiBNUHRycz4KYXV0byBhcnJvdyhUKiBvYmosIE1QdHIgbXB0ciwgTVB0cnMuLi4gbXB0cnMpCnsKICAgIHJldHVybiBhcnJvdyhvYmotPiptcHRyLCBtcHRycy4uLik7Cn0KCnRlbXBsYXRlIDx0eXBlbmFtZSBDb250YWluZXIsIHR5cGVuYW1lIFQsIHR5cGVuYW1lLi4uIERhdGFQdHJzPgphdXRvIHNlYXJjaEJ5RGF0YU1lbWJlciAoY29uc3QgQ29udGFpbmVyJiBjb250YWluZXIsIGNvbnN0IFQmIHQsIERhdGFQdHJzLi4uIHB0cnMpCnsKICAgIHJldHVybiBzdGQ6OmZpbmRfaWYoc3RkOjpiZWdpbihjb250YWluZXIpLCBzdGQ6OmVuZChjb250YWluZXIpLAogICAgICAgICAgICAgICAgWyZdKGNvbnN0IGF1dG8mZSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBhcnJvdyhlLCBwdHJzLi4uKSA9PSB0OwogICAgICAgICAgICAgICAgfSk7Cn0KCnN0cnVjdCBUaGluZyB7CiAgICBpbnQgSUQsIHZhbHVlOwogICAgc3RkOjpzdHJpbmcgbmFtZTsKICAgIFRoaW5nIChpbnQgaSwgaW50IHYsIGNvbnN0IHN0ZDo6c3RyaW5nJiBuKSA6IElEKGkpLCB2YWx1ZSh2KSwgbmFtZShuKSB7fQp9OwoKc3RydWN0IE9iamVjdCB7CiAgICBpbnQgcmFuazsKICAgIFRoaW5nKiB0aGluZzsKICAgIE9iamVjdCAoaW50IHIsIFRoaW5nKiB0KSA6IHJhbmsociksIHRoaW5nKHQpIHt9Cn07CgoKaW50IG1haW4oKSB7CiAgICBUaGluZyB0aGluZzEoNSwgNiwgIlNhbSIpOwogICAgT2JqZWN0IG8xKDgsICZ0aGluZzEpOwogICAgVGhpbmcgdGhpbmcyKDExLCA3LCAiTWFyayIpOwogICAgT2JqZWN0IG8yKDgsICZ0aGluZzIpOwogICAgVGhpbmcgdGhpbmczKDksIDEyLCAiUm9iIik7CiAgICBPYmplY3QgbzMoOCwgJnRoaW5nMyk7CiAgICBUaGluZyB0aGluZzQoMiwgMTEsICJUb20iKTsKICAgIE9iamVjdCBvNCg4LCAmdGhpbmc0KTsKICAgIHN0ZDo6bGlzdDxPYmplY3QqPiBvYmplY3RzeyZvMSwgJm8yLCAmbzMsICZvNH07CgogICAgY29uc3QgYXV0byBpdCA9IHNlYXJjaEJ5RGF0YU1lbWJlciAob2JqZWN0cywgMTEsICZPYmplY3Q6OnRoaW5nLCAmVGhpbmc6OnZhbHVlKTsKICAgIHN0ZDo6Y291dCA8PCAoKml0KS0+dGhpbmctPm5hbWUgPDwgJ1xuJzsgIC8vIFRvbSAodGhlIGRlc2lyZWQgb3V0cHV0KQp9