Topic: binary_function<>, operator()
Author: Duff@DIKU.DK (Allan Odgaard)
Date: Wed, 24 Sep 2003 15:22:36 +0000 (UTC) Raw View
Matthew Peltzer:
> [...] it would be real nice to be able to do this:
> [...] compare = new std::less<int>;
For this to work, operator() would need to be declared virtual, which
in many cases could impact performance.
---
[ 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: pdimov@mmltd.net (Peter Dimov)
Date: Fri, 26 Sep 2003 17:31:40 +0000 (UTC) Raw View
goose23@spu.edu (Matthew Peltzer) wrote in message news:<75a1cd5a.0309221256.742015e4@posting.google.com>...
> Why isn't operator() defined in std::binary_function<T, T, bool>?
>
> For example, it would be real nice to be able to do this:
> ---
> std::binary_function<int, int, bool>* compare;
> std::string str;
> int i, j;
>
> if(0 == str.compare("less")) compare = new std::less<int>;
> else if(0 == str.compare("equal")) compare = new std::equal_to<int>;
> else if(0 == str.compare("greater")) compare = new std::greater<int>;
>
> (*compare)(i,j);
>
> delete compare;
std::map< std::string, boost::function<bool(int, int)> > cmp_map;
cmp_map["less"] = std::less<int>();
cmp_map["equal"] = std::equal_to<int>();
cmp_map["greater"] = std::greater<int>();
std::string str;
int i, j;
cmp_map[str](i,j);
http://www.boost.org/doc/html/function.html
http://std.dkuug.dk/jtc1/sc22/wg21/docs/papers/2002/n1402.html
http://std.dkuug.dk/jtc1/sc22/wg21/docs/library_technical_report.html
---
[ 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: goose23@spu.edu (Matthew Peltzer)
Date: Mon, 29 Sep 2003 05:12:08 +0000 (UTC) Raw View
llewelly.at@xmission.dot.com wrote in message news:<86smmn61pd.fsf@mushroom.brsssget>...
> goose23@spu.edu (Matthew Peltzer) writes:
>
> > Why isn't operator() defined in std::binary_function<T, T, bool>?
>
> Because binary_function is not a polymorphic base class. The STL is
> not OO. The purpose of binary_function is to provide 3 typedefs
> with somewhat less typing, for use by function object adaptors.
>
> You can find a good explanation of what binary_function<> and friends
> are for Matt Austern's _Generic Programming and the STL_. You can
> find an explanation of why the STL is not OO in everyone's
> favorite Stepanov interview:
>
> http://www.stlport.org/resources/StepanovUSA.html
Out of the 5 responses, this is the only answer I find to be
sufficient. Thanks.
> > For example, it would be real nice to be able to do this:
> > ...
> > delete compare;
> [snip]
>
> Note your delete has undefined behavior; binary_function<> has a
> non-virtual destructor, and the dynamic type of compare's pointee
> is inconsistent with compare's static type.
Well of course. Hence binary_function<> should have a virtual
destructor as well as a virtual operator().
> There is nothing wrong with creating your own homebrew class to fill
> the role binary_function<> was never intended to fill.
Right. So, how can I do this and use the stl's binary_function<>
inheritors such as less<> and greater<>? I've considered writing a
partial specialization of binary_function<> (in effect, inserting my
own class between binary_function<> and its inheritors w/o modifying
the stl explicitly) for functors like less<T, T, bool>, but have not
had any success.
If this is not possible, then in my opinion it is just easier to use a
function pointer and write my own templated functions, ie:
template<class T> bool less(const T& arg1, const T& arg2) { return
arg1 < arg2; }
template<class T> bool greater(const T& arg1, const T& arg2) { return
arg1 > arg2; }
...
bool (*compare)(int, int) = less;
---
[ 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: goose23@spu.edu (Matthew Peltzer)
Date: Tue, 23 Sep 2003 05:40:15 +0000 (UTC) Raw View
Why isn't operator() defined in std::binary_function<T, T, bool>?
For example, it would be real nice to be able to do this:
---
std::binary_function<int, int, bool>* compare;
std::string str;
int i, j;
if(0 == str.compare("less")) compare = new std::less<int>;
else if(0 == str.compare("equal")) compare = new std::equal_to<int>;
else if(0 == str.compare("greater")) compare = new std::greater<int>;
(*compare)(i,j);
delete compare;
---
---
[ 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: llewelly.at@xmission.dot.com
Date: Tue, 23 Sep 2003 16:24:51 +0000 (UTC) Raw View
goose23@spu.edu (Matthew Peltzer) writes:
> Why isn't operator() defined in std::binary_function<T, T, bool>?
Because binary_function is not a polymorphic base class. The STL is
not OO. The purpose of binary_function is to provide 3 typedefs
with somewhat less typing, for use by function object adaptors.
You can find a good explanation of what binary_function<> and friends
are for Matt Austern's _Generic Programming and the STL_. You can
find an explanation of why the STL is not OO in everyone's
favorite Stepanov interview:
http://www.stlport.org/resources/StepanovUSA.html
>
> For example, it would be real nice to be able to do this:
> ---
> std::binary_function<int, int, bool>* compare;
> std::string str;
> int i, j;
>
> if(0 == str.compare("less")) compare = new std::less<int>;
> else if(0 == str.compare("equal")) compare = new std::equal_to<int>;
> else if(0 == str.compare("greater")) compare = new std::greater<int>;
>
> (*compare)(i,j);
>
> delete compare;
[snip]
Note your delete has undefined behavior; binary_function<> has a
non-virtual destructor, and the dynamic type of compare's pointee
is inconsistent with compare's static type.
There is nothing wrong with creating your own homebrew class to fill
the role binary_function<> was never intended to fill.
---
[ 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: johnchx2@yahoo.com (johnchx)
Date: Tue, 23 Sep 2003 18:54:51 +0000 (UTC) Raw View
goose23@spu.edu (Matthew Peltzer) wrote
> Why isn't operator() defined in std::binary_function<T, T, bool>?
>
> For example, it would be real nice to be able to do this:
> ---
> std::binary_function<int, int, bool>* compare;
> std::string str;
> int i, j;
>
> if(0 == str.compare("less")) compare = new std::less<int>;
> else if(0 == str.compare("equal")) compare = new std::equal_to<int>;
> else if(0 == str.compare("greater")) compare = new std::greater<int>;
>
> (*compare)(i,j);
>
> delete compare;
To get the behavior you illustrate above, operator() would have to be
a virtual member function. Virtual functions are generally slower
than non-virtuals (since the actual function address usually must be
looked up at runtime, and since virtual calls are difficult or
impossible to inline). The standard functors use non-virtual member
functions for maximum performance.
---
[ 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: usenet_cpp@lehrerfamily.com (Joshua Lehrer)
Date: Tue, 23 Sep 2003 18:55:11 +0000 (UTC) Raw View
goose23@spu.edu (Matthew Peltzer) wrote in message news:<75a1cd5a.0309221256.742015e4@posting.google.com>...
> Why isn't operator() defined in std::binary_function<T, T, bool>?
>
> For example, it would be real nice to be able to do this:
> ---
> std::binary_function<int, int, bool>* compare;
> std::string str;
> int i, j;
>
> if(0 == str.compare("less")) compare = new std::less<int>;
> else if(0 == str.compare("equal")) compare = new std::equal_to<int>;
> else if(0 == str.compare("greater")) compare = new std::greater<int>;
>
> (*compare)(i,j);
>
> delete compare;
> ---
>
Because that requires all operator() to be virtual, and requires all
function calls to operator() to go through dispatch, thus slowing them
down. On my compiler, if I pass a function object into a templated
method, the code is frequently inlined, with the function object being
discarded. This is much harder to do if the method is virtual.
If you want a class that behaves like that, make one, it is trivial.
Inherit from binary_function, and have a purely virtual method.
BTW, try to avoid raw pointers:
std::auto_ptr<std::binary_function<int, int, bool> > compare;
std::string str;
int i, j;
if(0 == str.compare("less")) compare.reset(new std::less<int>);
else if(0 == str.compare("equal")) compare.reset(new
std::equal_to<int>);
else if(0 == str.compare("greater")) compare.reset(new
std::greater<int>);
(*compare)(i,j);
joshua lehrer
factset research systems
NYSE:FDS
---
[ 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 ]