Topic: No not1/not2 replacement?


Author: petebecker@acm.org (Pete Becker)
Date: Sat, 11 Sep 2004 00:53:01 GMT
Raw View
Scott Meyers wrote:
>
> This strikes me as a problem.  Have I overlooked something, or should TR1
> include some kind of not1/not2 functionality that's as flexible as mem_fn?
>

tr1::mem_fn could support the type propogation mechanism used by the
standard, as tr1::function does.

--

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: Usenet@aristeia.com (Scott Meyers)
Date: Sat, 11 Sep 2004 02:05:11 GMT
Raw View
On Sat, 11 Sep 2004 00:53:01 GMT, Pete Becker wrote:
> tr1::mem_fn could support the type propogation mechanism used by the
> standard, as tr1::function does.

Does TR1 require that it do so?  Does the spec for mem_fn have anything to
say about the validity of this code from my previous post?

    find_if(v.begin(), v.end(),
            not1(tr1::mem_fn(&Widget::isOK)));

As I said, this fails when I use Boost as a TR1 proxy, but I realize that
Boost isn't TR1.

Scott

---
[ 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, 11 Sep 2004 03:54:10 GMT
Raw View
Scott Meyers wrote:
>
> On Sat, 11 Sep 2004 00:53:01 GMT, Pete Becker wrote:
> > tr1::mem_fn could support the type propogation mechanism used by the
> > standard, as tr1::function does.
>
> Does TR1 require that it do so?

No. That's why I said "could" and not "does." It was trivial to add it
to our implementation, though, and with the addition your code compiles.

--

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: Usenet@aristeia.com (Scott Meyers)
Date: Sun, 12 Sep 2004 00:03:05 GMT
Raw View
On Sat, 11 Sep 2004 03:54:10 GMT, Pete Becker wrote:
> Scott Meyers wrote:
> > Does TR1 require that it do so?
>
> No. That's why I said "could" and not "does." It was trivial to add it
> to our implementation, though, and with the addition your code compiles.

Is it too late to add this kind of requirement to TR1?  It'd be nice to
know that such code is portable.  I mean, really, shouldn't it be mandatory
that not1/not2 work with mem_fn as they are currently required to work with
mem_fun and mem_fun_ref?

Scott

---
[ 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@gmail.com (Peter Dimov)
Date: Sun, 12 Sep 2004 16:51:28 GMT
Raw View
Usenet@aristeia.com (Scott Meyers) wrote in message news:<MPG.1bac2e5c1def364698978f@news.hevanet.com>...
> On Sat, 11 Sep 2004 03:54:10 GMT, Pete Becker wrote:
> > Scott Meyers wrote:
> > > Does TR1 require that it do so?
> >
> > No. That's why I said "could" and not "does." It was trivial to add it
> > to our implementation, though, and with the addition your code compiles.
>
> Is it too late to add this kind of requirement to TR1?

It is not possible to add argument_type/first_argument_type to mem_fn
that is correct in all cases. You can arbitrarily pick one of T* (as
boost::mem_fn does), T&, or shared_ptr<T>. In my experience, this is
doing users a disservice. The first argument of mem_fn cannot be
expressed by a single typedef.

If by "this kind of requirement" you mean that we ought to require
that not1/not2 work with mem_fn, no, this is not possible to do with
TR1, since it can't make changes to existing standard library
components, AFAIK.

---
[ 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, 12 Sep 2004 20:16:45 GMT
Raw View
Scott Meyers wrote:
>
> On Sat, 11 Sep 2004 03:54:10 GMT, Pete Becker wrote:
> > Scott Meyers wrote:
> > > Does TR1 require that it do so?
> >
> > No. That's why I said "could" and not "does." It was trivial to add it
> > to our implementation, though, and with the addition your code compiles.
>
> Is it too late to add this kind of requirement to TR1?  It'd be nice to
> know that such code is portable.  I mean, really, shouldn't it be mandatory
> that not1/not2 work with mem_fn as they are currently required to work with
> mem_fun and mem_fun_ref?
>

I made that suggestion on the libraries reflector yesterday. No
responses yet. <g>

--

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: pdimov@gmail.com (Peter Dimov)
Date: Sun, 12 Sep 2004 20:17:01 GMT
Raw View
Usenet@aristeia.com (Scott Meyers) wrote in message news:<MPG.1baa8e38b51cab8498978c@news.hevanet.com>...
> With the advent of TR1, we don't have to remember mem_fun vs. mem_fun_ref.
> We just use mem_fn.  We don't have to remember bind1st vs. bind2nd.  We
> just use bind.  But my impression is that we still have to remember not1
> vs. not2, e.g., there is no adapter called "negate" or some such that
> unifies the two.  (We can't just use "not", as it's an alternative spelling
> for "!".)  Is this correct, or am I overlooking something on the
> not1/not2 front?

This is correct. tr1::mem_fn/tr1::bind do not offer a convenient
syntax for negating the result. The inconvenient not1 equivalent is

  bind( logical_not<bool>(), bind(f, _1) );

and the corresponding member function syntax is

  bind( logical_not<bool>(), bind(&X::f, _1) );

I've been experimenting with

  !bind(f, _1)
  !bind(&X::f, _1)

as a shorthand notation. But this is not in Boost yet, it wasn't part
of the tr1::bind proposal, and apparently it is too late now for it to
go into TR1.

See also

http://groups.google.com/groups?selm=7dc3b1ea.0405260421.29ae21b5%40posting.google.com

My preferred solution at the moment is to just define
&Widget::is_no_OK, when I need to negate the result of &Widget::is_OK.
;-)

---
[ 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@aristeia.com (Scott Meyers)
Date: Mon, 13 Sep 2004 08:27:51 GMT
Raw View
On Sun, 12 Sep 2004 16:51:28 GMT, Peter Dimov wrote:
> If by "this kind of requirement" you mean that we ought to require
> that not1/not2 work with mem_fn, no, this is not possible to do with
> TR1, since it can't make changes to existing standard library
> components, AFAIK.

Right.  Sloppy wording on my part, sorry.  What I meant to ask about was
the possibility of TR1 adding not1/not2-like functionality that would work
with mem_fn.  Maybe a function template called negate or something like
that.  Based on your later post, I get the impresson that that's either
unlikely or technically quite challenging or both.  Too bad :-(

Scott


---
[ 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@aristeia.com (Scott Meyers)
Date: Fri, 10 Sep 2004 03:52:10 GMT
Raw View
With the advent of TR1, we don't have to remember mem_fun vs. mem_fun_ref.
We just use mem_fn.  We don't have to remember bind1st vs. bind2nd.  We
just use bind.  But my impression is that we still have to remember not1
vs. not2, e.g., there is no adapter called "negate" or some such that
unifies the two.  (We can't just use "not", as it's an alternative spelling
for "!".)  Is this correct, or am I overlooking something on the
not1/not2 front?

Thanks,

Scott

---
[ 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@aristeia.com (Scott Meyers)
Date: Fri, 10 Sep 2004 23:15:22 GMT
Raw View
When I posted asking about a not1/not2 replacement in TR1, I was just
worried about syntax, but now I think there is a functional problem, too.
TR1's mem_fn is nicely flexible:

  mem_fn(&X::f), where f is a member function of X, returns an object
  through which &X::f can be called given a pointer, a smart pointer, an
  iterator, or a reference to X...

The return type of mem_fn is unspecified, but I'm imagining it's a class
with a templatized operator().  That's cool until I try to pass such an
object to not1/not2, as these classes are nowhere near as flexible: they
want to grab a typedef identifying the parameter type(s) taken by
operator() in the object they are wrapping.  There's no such typedef for
the objects returned by mem_fn.  The result, I imagine, is that it's
possible to use mem_fn with a container of smart pointers and a predicate,
but it's not possible to do exactly the same thing with a negated
predicate.

My test program, using boost as a tr1 proxy, yields the behavior I expect:

  #include "boost/mem_fn.hpp"
  #include "boost/smart_ptr.hpp"
  #include <vector>
  #include <algorithm>

  class Widget {
  public:
    bool isOK() const;
  };


  int main()
  {
    using namespace std;
    namespace tr1 = boost;

    vector<tr1::shared_ptr<Widget> > v;

    find_if(v.begin(), v.end(),
            tr1::mem_fn(&Widget::isOK));        // compiles

    find_if(v.begin(), v.end(),
            not1(tr1::mem_fn(&Widget::isOK)));  // doesn't compile
  }

This strikes me as a problem.  Have I overlooked something, or should TR1
include some kind of not1/not2 functionality that's as flexible as mem_fn?

Scott

---
[ 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                       ]