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                       ]