Confusing title, hopefully some code will clarify:
struct MyNestedType {
void func();
};
struct MyType {
MyNestedType* nested;
}
std::vector<MyType> vec;
// ... populate vec
// I want something approximating this line, but that doesn't use made-up C++!
std::for_each(vec.begin(), vec.end(), std::mem_fun_ref(&MyType::nested->func));
So basically I want to call a method on each element of the container, but it's not actually a method of the type, it's some method on a contained type... I know I could write a function object to 'pass on' the call but there are a few methods I'd like to call and that will get messy.
Any ideas?
Why don't you just use a simple for-loop?
for(vector<MyType>::iterator i = vec.begin(); i != vec.end(); ++i)
i->nested->func();
Alternatively, you could use lambda expressions or boost::foreach
FOREACH(MyType x, vec)
x.nested->func();
You can build your up expression with binders and mem_funs, but this will get very messy and confusing! There is no advantage in putting everything in one std::foreach line.
You can use such functor
template <typename T, T* MyType::* TMember, void (T::* TNestedMember)() >
struct Caller {
Caller() {
}
template <typename TObject>
void operator()(TObject object) {
(object.*TMember->*TNestedMember)();
}
};
To solve your problem
struct MyNestedType {
MyNestedType(int a):
a_(a){
}
void func() {
std::cout << "MyNestedType::func " << a_ << std::endl;
}
void foo() {
std::cout << "MyNestedType::foo " << a_ << std::endl;
}
int a_;
};
struct MyType {
MyNestedType* nested;
};
int main()
{
std::vector<MyType> vec;
std::auto_ptr<MyNestedType> nt1(new MyNestedType(2));
std::auto_ptr<MyNestedType> nt2(new MyNestedType(5));
MyType t1 = {nt1.get()};
MyType t2 = {nt2.get()};
vec.push_back(t1);
vec.push_back(t2);
std::for_each(vec.begin(), vec.end(),
Caller<MyNestedType, &MyType::nested, &MyNestedType::func>());
std::for_each(vec.begin(), vec.end(),
Caller<MyNestedType, &MyType::nested, &MyNestedType::foo>());
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With