Topic: Defect Report: unary_function and binary_function should have
Author: petebecker@acm.org (Pete Becker)
Date: Thu, 26 Aug 2004 17:42:49 GMT Raw View
David Abrahams wrote:
>
> petebecker@acm.org (Pete Becker) writes:
>
> > David Abrahams wrote:
> >>
> >> I think the prominent operator() works nearly as well with fewer ill
> >> effects.
> >>
> >
> > Except for function object types that don't define an operator().
>
> Interesting concept. Example?
>
A function object that wraps a pointer to function and provides a
conversion operator that returns the pointer. As we discussed last week
on the WG21 libraries reflector, this eliminates any forwarding issues,
because the compiler calls the function directly through the pointer.
--
Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: petebecker@acm.org (Pete Becker)
Date: Fri, 27 Aug 2004 02:40:27 GMT Raw View
David Abrahams wrote:
>
> petebecker@acm.org (Pete Becker) writes:
>
> > A function object that wraps a pointer to function and provides a
> > conversion operator that returns the pointer. As we discussed last week
> > on the WG21 libraries reflector, this eliminates any forwarding issues,
> > because the compiler calls the function directly through the
> > pointer.
>
> I thought Peter Dimov had some examples where the implicit conversion
> was insufficient?
Nope. It works in all cases.
--
Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: falk.tannhauser@crf.canon.fr (=?ISO-8859-1?Q?Falk_Tannh=E4user?=)
Date: Wed, 25 Aug 2004 17:17:11 GMT Raw View
John Dibling wrote:
>> but I also think the benefits of using [binary_function and unary_func=
tion] is pretty much nonexistent. =20
>=20
> IMO using them does have 1 distinct advantage: the self-documentation
> provided by semantic clarity. Even newer STL programmers can
> recognize what the purpose in life is for a class derived from
> x_function (e.g., it is used as a functor by some algorithm), and
> maintain that code appropriately.
However, using them is not always feasible for custom functors.
Recently, I found myself writing something like
template<typename T>
struct Comparator
{
// ... quite a complex implementation
bool operator(T const& a, T const& b) { /* something complicated */ }
bool operator(T const* pa, T const* pb) { return operator()(*pa, *pb); =
}
bool operator(boost::shared_ptr<T> const& pa, boost::shared_ptr<T> cons=
t& pb) { return operator()(*pa, *pb); }
};
allowing me, for example, to sort both vectors of values and vectors of
(possibly smart) pointers. There is no good binary_function instantiation
to derive from, unless one performs partial specialisations like
template<typename T>
struct Comparator : public std::binary_function<T, T, bool>
{
// ...
bool operator(T const& a, T const& b) { /* something complicated */ }
};
template<typename T>
struct Comparator<T const*, T const*> : public std::binary_function<T con=
st*, T const*, bool>
{
// Lots of code duplication :-(
bool operator(T const* a, T const* b) { /* something complicated */ }
};
Here the costs of using binary_function clearly outweighs any possible
benefits, IMO.
Falk Tannh=E4user
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: petebecker@acm.org (Pete Becker)
Date: Thu, 26 Aug 2004 00:10:07 GMT Raw View
David Abrahams wrote:
>
> I think the prominent operator() works nearly as well with fewer ill
> effects.
>
Except for function object types that don't define an operator().
--
Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: austern@well.com (Matt Austern)
Date: Tue, 24 Aug 2004 02:46:27 GMT Raw View
dave@boost-consulting.com (David Abrahams) writes:
> No. My advice is that they should not be used because they provide
> little or no benefit, they're hard to use correctly compared to what
> little benefit they might provide, and they come with some pitfalls,
> among them that some people to waste time worrying about whether they
> should have virtual dtors. It comes up periodically in this NG.
FWIW, I agree with that advice. I think the pitfalls of
unary_function and binary_function to be pretty much theoretical (has
anyone really seen code that tries to delete a function object through
a pointer to one of those classes?), but I also think the benefits of
using those base classes is pretty much nonexistent. Same with
std::iterator. I don't use any of those three classes, and I don't
see a good reason why anyone should.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: petebecker@acm.org (Pete Becker)
Date: Tue, 24 Aug 2004 02:54:07 GMT Raw View
David Abrahams wrote:
>
> petebecker@acm.org (Pete Becker) writes:
>
> > David Abrahams wrote:
> >>
> >> petebecker@acm.org (Pete Becker) writes:
> >>
> >> Maybe achieving optimal size for composed function objects is not
> >> important enough to make it part of the guideline, though.
> >
> > Stating conclusions rather than explaining them is not very
> > persuasive.
>
> I didn't realize you had misunderstood about the EBO thing. Above is
> the first time you gave an indication of not understanding it.
Above is the first time you mentioned it. I'm sure many people reading
this thread who had no idea what your conclusory statement meant. Always
keep your audience in mind.
--
Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: petebecker@acm.org (Pete Becker)
Date: Sat, 21 Aug 2004 18:19:43 GMT Raw View
David Abrahams wrote:
>
> I would suggest a guideline for novices (and
> experts, too) that says "don't use std::unary_function or
> std::binary_function".
>
That seems a bit extreme. "Don't create pointers to std::unary_function
or std::binary_function" is somewhat closer, or "Don't delete pointers
to std::unary_function or std::binary_function" would be more accurate.
--
Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: petebecker@acm.org (Pete Becker)
Date: Sun, 22 Aug 2004 19:25:58 GMT Raw View
David Abrahams wrote:
>
> petebecker@acm.org (Pete Becker) writes:
>
> > David Abrahams wrote:
> >>
> >> I would suggest a guideline for novices (and
> >> experts, too) that says "don't use std::unary_function or
> >> std::binary_function".
> >>
> >
> > That seems a bit extreme. "Don't create pointers to std::unary_function
> > or std::binary_function" is somewhat closer, or "Don't delete pointers
> > to std::unary_function or std::binary_function" would be more accurate.
>
> Doesn't account for the EBO-suppression problem.
Huh?
> Maybe achieving
> optimal size for composed function objects is not important enough to
> make it part of the guideline, though.
Stating conclusions rather than explaining them is not very persuasive.
>
> That said, these templates don't provide much benefit, do they?
> There's no real abstraction. It's hard to remember the argument order
> -- explicitly making a result_type typedef (and first_argument_type or
> whatever where neccessary) would often be clearer and less
> error-prone... and with tr1 bind, result_type is all you'll ever
> need. Pretty soon even that will be history as more compilers
> support decltype.
>
Okay, so your advice is that since other approaches may become possible
in the future, current approaches should not be used.
--
Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: Joe Gottman <jgottman@carolina.rr.com>
Date: Thu, 19 Aug 2004 14:32:27 +0000 (UTC) Raw View
[ note: forwarded to C++ Comittee - sdc ]
The classes std::unary_function and std::binary_function are both
designed to be inherited from but contain no virtual functions. This makes
it too easy for a novice programmer to write code like
binary_function<int, int, int> *p = new plus<int>;
delete p;
There are two common ways to prevent this source of undefined behavior: give
the base class a public virtual destructor, or give it a protected
nonvirtual destructor. Since unary_function and binary_function have no
other virtual functions, (note in particular the absence of an
operator()() ), it would cost too much to give them public virtual
destructors. Therefore, they should be given protected nonvirtual
destructors.
Proposed resolution:
Change Paragraph 20.3.1 of the Standard from
template <class Arg, class Result>
struct unary_function {
typedef Arg argument_type;
typedef Result result_type;
};
template <class Arg1, class Arg2, class Result>
struct binary_function {
typedef Arg1 first_argument_type;
typedef Arg2 second_argument_type;
typedef Result result_type;
};
to
template <class Arg, class Result>
struct unary_function {
typedef Arg argument_type;
typedef Result result_type;
protected:
~unary_function() {}
};
template <class Arg1, class Arg2, class Result>
struct binary_function {
typedef Arg1 first_argument_type;
typedef Arg2 second_argument_type;
typedef Result result_type;
protected:
~binary_function() {}
};
Joe Gottman
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]