• ### Popular Now

• 15
• 15
• 11
• 9
• 10

#### Archived

This topic is now archived and is closed to further replies.

# mem_fun_ref question

This topic is 5116 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

class X
{
//...

bool f() const;
};

class Y
{
//...

bool f() const
{
for_each(v.begin(), v.end(), mem_fun_ref(&X::f));
}
vector<X> v;
};
Is there any way to check if X::f() returns false for any of the objects in v?

##### Share on other sites
Either use std::transform and process the individual results, or write a stateful functor, something like:

template<class Functor>struct any_false_fn: std::unary_function<typename Functor::argument_type,                        typename Functor::result_type>{   Functor fn_;   bool any_false;   any_false_fn(const Functor& fn)   : fn_ (fn), any_false(false)   {}   result_type operator()(const argument_type& arg)   {      result_type result = fn_(arg);      any_false |= !result;      return result;   }};template<class Functor>any_false_fn<Functor> any_false(const Functor& fn){   return any_false_fn<Functor>(fn);}result = std::for_each( v.begin(), v.end(), any_false(mem_fun_ref(&X::f)) ).any_false;

std::for_each returns the functor object it was passed originally.

“Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.”
— Brian W. Kernighan

##### Share on other sites
use std::accumulate with an appropriately written functor: compose boolean_and with mem_fun_ref. Pass "true" in as the init. If the result is false, at least one element returned false.

This sort of grotesque not-quite-lambda-calculus is why I tend not to use STL algorithms much. std::accumulate is pretty cool, tho. (and quite useful, in surprising situations.)

"Sneftel is correct, if rather vulgar." --Flarelocke

[edited by - sneftel on March 20, 2004 6:09:30 PM]

good call.

##### Share on other sites
Thank you both. I'll test it tomorrow, it's night here
Edit: I realized I didn't really understand your idea sneftel. I tried:
bool result = std::accumulate(v.begin(), v.end(), true, std::bind2nd(std::logical_and<bool>(), std::mem_fun_ref(&X::f)));
and that didn't compile. Errors: error C2440: 'initializing' : cannot convert from 'const std::const_mem_fun_ref_t<_Result,_Ty>' to 'std::binary_function<_Arg1,_Arg2,_Result>::second_argument_type'
with
[
_Result=bool,
_Ty=X
]
and
[
_Arg1=bool,
_Arg2=bool,
_Result=bool
]
and error C2064: term does not evaluate to a function taking 2 arguments
class does not define an 'operator()' or a user defined conversion operator to a pointer-to-function or reference-to-function that takes appropriate number of arguments
: see reference to function template instantiation '_Ty std::accumulate::const_iterator,bool,std::binder2nd<_Fn2>>(_InIt,_InIt,_Ty,std::binder2nd<_Fn2>)' being compiled
with
[
_Ty=bool,
_Fn2=std::logical_and,
_InIt=std::vector::const_iterator
]

[edited by - Eriond on March 20, 2004 6:48:46 PM]

##### Share on other sites
One other idea: if you need (or don''t mind) short-circuit evaluation (which seems likely since your member function is const), then you can just use:

return (find_if(v.begin(), v.end(), std::not1(std::mem_fun_ref(&X::f))) != v.end());

##### Share on other sites
quote:
Original post by Eriond
Edit: I realized I didn''t really understand your idea sneftel. I tried:

I think he literally meant compose, not bind. The down side is that there is no standard compose function object. One quick hack would be to use:
struct thunk {  bool operator()(bool lhs, const X & rhs) {    return lhs && rhs.f();  }};std::accumulate(v.begin(), v.end(), true, thunk());

##### Share on other sites
Oh, I see. I''ll use the compose functions from Josuttis'' book. And your way(find_if) is good enought for me.

##### Share on other sites
Darnit, I knew I was going to run into that... when I actually used algorithms a fair amount, I used a lot of Boost stuff (including compose), and I have trouble remembering what's in std and what isn't. IIRC, compose is in there, along with quite a few other useful ones. Of course, Boost also has the lambda library, to obviate a lot of that with a minimal runtime cost.

"Sneftel is correct, if rather vulgar." --Flarelocke

[edited by - sneftel on March 20, 2004 11:50:03 PM]