Chris Uzdavinis said on 24.4.2008 23:43:
> The only code you have that is really unique to this problem is the
> test for whether the element should be erased or not. Factor that out
> into its own inlined function object to be a simple predicate:
>
> struct is_odd
> {
> bool operator()(int num) const { return num & 1; }
> };
>
Great example, just want to add a bit.
With the little help of STL extensions present in some
compilers/libraries (I know G++ has it, VS 2003 does not :() is odd can
also be expresses using standard (with extension) functors.
Source taken from libstdc++ functional header.
/// An \link SGIextensions SGI extension \endlink.
template <class _Operation1, class _Operation2>
class unary_compose
: public unary_function<typename _Operation2::argument_type,
typename _Operation1::result_type>
{
protected:
_Operation1 _M_fn1;
_Operation2 _M_fn2;
public:
unary_compose(const _Operation1& __x, const _Operation2& __y)
: _M_fn1(__x), _M_fn2(__y) {}
typename _Operation1::result_type
operator()(const typename _Operation2::argument_type& __x) const {
return _M_fn1(_M_fn2(__x));
}
};
/// An \link SGIextensions SGI extension \endlink.
template <class _Operation1, class _Operation2>
inline unary_compose<_Operation1,_Operation2>
compose1(const _Operation1& __fn1, const _Operation2& __fn2)
{
return unary_compose<_Operation1,_Operation2>(__fn1, __fn2);
}
>
> Then rewrite delete_odd using standard library function remove_if
> which uses your predicate:
>
> #include <algorithm>
>
> void delete_odd(int_list_t & L)
> {
> // move the even elements to the front of the list
> int_list_t::iterator logical_end =
> std::remove_if(L.begin(), L.end(), is_odd());
>
> // get rid of odd values that are now at the end of the list.
> L.erase(logical_end, L.end());
> }
Now we can write this like:
void delete_odd(int_list_t & L)
{
// move the even elements to the front of the list
int_list_t::iterator logical_end =
std::remove_if(L.begin(), L.end(),
compose1(bind2nd(equal_to<int>(), 0),
bind2nd(modulus<int>(), 2))
);
// get rid of odd values that are now at the end of the list.
L.erase(logical_end, L.end());
}
Naturally for such a simple example your code is shorter and probably
more clear, but in some other cases, especially on stl libs where
compose1 (and/or compose2) is sup****ted I prefer using standard functors
if/when available.
--
Tomy.
[ See http://www.gotw.ca/resources/clcm.htm
for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


|