|
Boost : |
From: John Maddock (John_Maddock_at_[hidden])
Date: 2000-05-16 06:36:50
Mark,
>They certainly did, thank you! I now have it all working with
both C++Builder 4 and g++, including the binders. I'll post an
updated version to the vault shortly.<
I let a little buglet creep into the code I posted:
template <class Predicate>
unary_negate<typename make_functor<Predicate>::type> not1(const Predicate&
pred)
{
return unary_negate<typename make_functor<Predicate>::type>((typename
make_functor<Predicate>::type)pred);
}
The type-cast here was a C++ Builder specific workaround - C++ Builder
seems to treat references to functions and pointers to functions as the
same type, so "const F&" gets degraded to "const F*" which means it can't
be passed to the function objects constructor without a const_cast. The
problem is that if T is a function object, then the cast generates a
temporary copy of the object, one workaround is to add a "cast_type" member
to make_functor (this ain't pretty but it does work!), here is my revised
test case:
#include <typeinfo>
#include <iostream>
#include <functional>
#include <boost/call_traits.hpp>
namespace boost{
template <class Operation>
struct unary_traits
{
typedef typename Operation::result_type result_type;
typedef typename Operation::argument_type argument_type;
};
template <class R, class A>
struct unary_traits<R(*)(A)>
{
typedef R result_type;
typedef A argument_type;
};
template <class F>
struct make_functor_ind;
template <class T>
struct make_functor_ind<T*>
{
typedef T type;
typedef const T& cast_type;
};
template <class R, class A>
struct make_functor_ind<R (*)(A)>
{
typedef R(*type)(A);
typedef R(*cast_type)(A);
};
template <class F>
struct make_functor : public make_functor_ind<F*>{};
template <class R, class A>
struct make_functor<R (*)(A)>
{
typedef R(*type)(A);
typedef R(*cast_type)(A);
};
//
--------------------------------------------------------------------------
// unary_negate, not1
//
--------------------------------------------------------------------------
template <class Predicate>
class unary_negate
: public std::unary_function<typename
unary_traits<Predicate>::argument_type,bool>
{
public:
explicit unary_negate(const Predicate &x)
:
pred(x)
{}
bool operator()(typename call_traits<typename
unary_traits<Predicate>::argument_type>::param_type x) const
{
return !pred(x);
}
private:
Predicate pred;
};
template <class Predicate>
unary_negate<typename make_functor<Predicate>::type> not1(const Predicate&
pred)
{
return unary_negate<typename make_functor<Predicate>::type>
((typename make_functor<Predicate>::cast_type)(pred));
}
} // boost
bool f1(int i)
{ return (i == 0); }
int main()
{
if(boost::not1(f1)(0) != boost::not1(std::ptr_fun(f1))(0))
exit(1);
return 0;
}
- John.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk