Attached is a sample code that implements the three approaches that Lars has been playing with.
std::string const search_name = "william"; FooVec::const_iterator const begin = foovec.begin(); FooVec::const_iterator const end = foovec.end(); FooVec::const_iterator const it = std::find_if(begin, end, #if CASE == 1 SameNames(search_name)); #elif CASE == 2 boost::bind(std::equal_to<std::string>(), boost::bind(&Foo::name, _1), search_name)); #elif CASE == 3 bind(&Foo::name, _1) == search_name); #endif Compile, eg: $ g++ -DCASE=1 -Iboost/boost-1.30.2 -O2 -o trial trial.C $ CASE=3; $ g++ -DCASE=$CASE -Iboost/boost-1.30.2 -O2 -S -o trial_case$CASE.s trial.C I have little idea how to make sense of the assembler code but, at least for gcc 3.3, it appears that the named functor approach produces the smallest-sized executable. $ size trial_case? text data bss dec hex filename 7850 816 8 8674 21e2 trial_case1 9510 840 16 10366 287e trial_case2 9530 872 8 10410 28aa trial_case3 Regards, Angus
#include <iostream> #include <string> #include <vector> #if !defined(CASE) || (CASE != 1 && CASE != 2 && CASE != 3) #error Please compile -DCASE=[123] #endif #if CASE == 2 #include <boost/bind.hpp> using namespace boost; #endif #if CASE == 3 #include <boost/lambda/bind.hpp> #include <boost/lambda/lambda.hpp> using namespace boost::lambda; #endif class Foo { std::string name_; public: Foo(std::string const & name) : name_(name) {} std::string const & name() const { return name_; } }; char const * const names[] = { "alfred", "ben", "chris", "david", "edgar", "fred", "graham", "henry", "ian", "james", "kenneth", "laurie", "mark", "nigel", "oprah", "peter", "quentin", "rashid", "stewart", "thomas", "uriah", "veronique", "william", "xang", "yashin", "zebedee" }; std::size_t const names_size = sizeof(names) / sizeof(names[0]); #if CASE == 1 struct SameNames { SameNames(std::string const & name) : name_(name) {} bool operator()(Foo const & foo) const { return name_ == foo.name(); } private: std::string name_; }; #endif int main() { typedef std::vector<Foo> FooVec; FooVec const foovec(names, names + names_size); std::string const search_name = "william"; FooVec::const_iterator const begin = foovec.begin(); FooVec::const_iterator const end = foovec.end(); #if CASE == 1 FooVec::const_iterator const it = std::find_if(begin, end, SameNames(search_name)); #elif CASE == 2 FooVec::const_iterator const it = std::find_if(begin, end, boost::bind(std::equal_to<std::string>(), boost::bind(&Foo::name, _1), search_name)); #elif CASE == 3 FooVec::const_iterator const it = std::find_if(begin, end, bind(&Foo::name, _1) == search_name); #endif if (it == end) std::cout << "Name '" << search_name << "' not found" << std::endl; else std::cout << "Name '" << search_name << "' found at pos " << std::distance(begin, it) << std::endl; return 0; }