// Copyright (C) 2009-2012 Lorenzo Caminiti // Distributed under the Boost Software License, Version 1.0 // (see accompanying file LICENSE_1_0.txt or a copy at // http://www.boost.org/LICENSE_1_0.txt) // Home at http://www.boost.org/libs/local_function //[impl_tparam_tricks #include #include #include // Casting functor trick. struct casting_func { explicit casting_func(void* obj, void (*call)(void*, const int&)) : obj_(obj), call_(call) {} // Unfortunately, function pointer call is not inlined. inline void operator()(const int& num) { call_(obj_, num); } private: void* obj_; void (*call_)(void*, const int&); }; // Virtual functor trick. struct virtual_func { struct interface { // Unfortunately, virtual function call is not inlined. inline virtual void operator()(const int&) {} }; explicit virtual_func(interface& func): func_(&func) {} inline void operator()(const int& num) { (*func_)(num); } private: interface* func_; }; int main(void) { int sum = 0, factor = 10; // Local class for local function. struct local_add : virtual_func::interface { explicit local_add(int& _sum, const int& _factor) : sum_(_sum), factor_(_factor) {} inline void operator()(const int& num) { body(sum_, factor_, num); } inline static void call(void* obj, const int& num) { local_add* self = static_cast(obj); self->body(self->sum_, self->factor_, num); } private: int& sum_; const int& factor_; inline void body(int& sum, const int& factor, const int& num) { sum += factor * num; } } add_local(sum, factor); casting_func add_casting(&add_local, &local_add::call); virtual_func add_virtual(add_local); std::vector v(10); std::fill(v.begin(), v.end(), 1); // std::for_each(v.begin(), v.end(), add_local); // Error but OK on C++11. std::for_each(v.begin(), v.end(), add_casting); // OK. std::for_each(v.begin(), v.end(), add_virtual); // OK. BOOST_TEST(sum == 200); return boost::report_errors(); } //]