Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c++ > #8189 > unrolled thread

Problem with functor, maybe I need operator== for my struct?

Started byFencer <no.i.dont@want.mail.from.spammers.invalid>
First post2011-07-25 13:25 +0200
Last post2011-07-25 07:27 -0700
Articles 8 — 3 participants

Back to article view | Back to comp.lang.c++


Contents

  Problem with functor, maybe I need operator== for my struct? Fencer <no.i.dont@want.mail.from.spammers.invalid> - 2011-07-25 13:25 +0200
    Re: Problem with functor, maybe I need operator== for my struct? Leigh Johnston <leigh@i42.co.uk> - 2011-07-25 12:38 +0100
      Re: Problem with functor, maybe I need operator== for my struct? Fencer <no.i.dont@want.mail.from.spammers.invalid> - 2011-07-25 13:40 +0200
    Re: Problem with functor, maybe I need operator== for my struct? Saeed Amrollahi <amrollahi.saeed@gmail.com> - 2011-07-25 05:14 -0700
      Re: Problem with functor, maybe I need operator== for my struct? Leigh Johnston <leigh@i42.co.uk> - 2011-07-25 13:52 +0100
        Re: Problem with functor, maybe I need operator== for my struct? Saeed Amrollahi <amrollahi.saeed@gmail.com> - 2011-07-25 06:46 -0700
          Re: Problem with functor, maybe I need operator== for my struct? Leigh Johnston <leigh@i42.co.uk> - 2011-07-25 15:00 +0100
            Re: Problem with functor, maybe I need operator== for my struct? Saeed Amrollahi <amrollahi.saeed@gmail.com> - 2011-07-25 07:27 -0700

#8189 — Problem with functor, maybe I need operator== for my struct?

FromFencer <no.i.dont@want.mail.from.spammers.invalid>
Date2011-07-25 13:25 +0200
SubjectProblem with functor, maybe I need operator== for my struct?
Message-ID<99525sF1frU1@mid.individual.net>
Hello, I am very rusty in C++ and I'm having some problems: I have a 
std::set<SomeClass> and I need to look through the set to find if any of 
the instances of SomeClass that it contains has a particular value for 
one of its data members. I know I could simply iterate through the set 
myself and check every SomeClass instance if any of them is a match, but 
I tried to do it using functors instead.
The following simplified test program does not build, and it seems to be 
that operator== is missing for the struct s1. Could you gurus help me 
explain why my test program does not build and how I should fix it?

#include <algorithm>
#include <functional>
#include <set>

using namespace std;

struct s1
{
    s1(int u, int v) : u(u), v(v) {}

    int u, v;
};

struct OnV : public unary_function<s1, bool>
{
    explicit OnV(int v) : v(v) {}

    bool operator()(s1 const& inst) const
    {
       return v == inst.v;
    }

    int v;
};

int main()
{
    set<s1> a_set;

    find(a_set.begin(), a_set.end(), OnV(4711));
}

$ g++ -Wall -Wextra -std=c++98 -pedantic functor.cpp -o functor.exe
/usr/lib/gcc/i686-pc-cygwin/4.3.4/include/c++/bits/stl_algo.h: In 
function ‘_InputIterator std::__find(_InputIterator, _InputIterator, 
const _Tp&, std::input_iterator_tag) [with _InputIterator = 
std::_Rb_tree_const_iterator<s1>, _Tp = OnV]’:
/usr/lib/gcc/i686-pc-cygwin/4.3.4/include/c++/bits/stl_algo.h:3814: 
instantiated from ‘_IIter std::find(_IIter, _IIter, const _Tp&) [with 
_IIter = std::_Rb_tree_const_iterator<s1>, _Tp = OnV]’
functor.cpp:30:   instantiated from here
/usr/lib/gcc/i686-pc-cygwin/4.3.4/include/c++/bits/stl_algo.h:151: 
error: no match for ‘operator==’ in 
‘__first.std::_Rb_tree_const_iterator<_Tp>::operator* [with _Tp = s1]() 
== __val’

Thank you for reading and thanks for any help! Even though I could use 
the alternative solution I mentioned above that does not involve 
functors, I wanted to know what I did wrong with my functor and 
hopefully learn something from your replies.

- Fencer

[toc] | [next] | [standalone]


#8190

FromLeigh Johnston <leigh@i42.co.uk>
Date2011-07-25 12:38 +0100
Message-ID<k--dnZFpWvcryLDTnZ2dnUVZ8gydnZ2d@giganews.com>
In reply to#8189
On 25/07/2011 12:25, Fencer wrote:
> Hello, I am very rusty in C++ and I'm having some problems: I have a
> std::set<SomeClass> and I need to look through the set to find if any of
> the instances of SomeClass that it contains has a particular value for
> one of its data members. I know I could simply iterate through the set
> myself and check every SomeClass instance if any of them is a match, but
> I tried to do it using functors instead.
> The following simplified test program does not build, and it seems to be
> that operator== is missing for the struct s1. Could you gurus help me
> explain why my test program does not build and how I should fix it?
>
> #include <algorithm>
> #include <functional>
> #include <set>
>
> using namespace std;
>
> struct s1
> {
> s1(int u, int v) : u(u), v(v) {}
>
> int u, v;
> };
>
> struct OnV : public unary_function<s1, bool>
> {
> explicit OnV(int v) : v(v) {}
>
> bool operator()(s1 const& inst) const
> {
> return v == inst.v;
> }
>
> int v;
> };
>
> int main()
> {
> set<s1> a_set;
>
> find(a_set.begin(), a_set.end(), OnV(4711));
> }
>
> $ g++ -Wall -Wextra -std=c++98 -pedantic functor.cpp -o functor.exe
> /usr/lib/gcc/i686-pc-cygwin/4.3.4/include/c++/bits/stl_algo.h: In
> function ‘_InputIterator std::__find(_InputIterator, _InputIterator,
> const _Tp&, std::input_iterator_tag) [with _InputIterator =
> std::_Rb_tree_const_iterator<s1>, _Tp = OnV]’:
> /usr/lib/gcc/i686-pc-cygwin/4.3.4/include/c++/bits/stl_algo.h:3814:
> instantiated from ‘_IIter std::find(_IIter, _IIter, const _Tp&) [with
> _IIter = std::_Rb_tree_const_iterator<s1>, _Tp = OnV]’
> functor.cpp:30: instantiated from here
> /usr/lib/gcc/i686-pc-cygwin/4.3.4/include/c++/bits/stl_algo.h:151:
> error: no match for ‘operator==’ in
> ‘__first.std::_Rb_tree_const_iterator<_Tp>::operator* [with _Tp = s1]()
> == __val’
>
> Thank you for reading and thanks for any help! Even though I could use
> the alternative solution I mentioned above that does not involve
> functors, I wanted to know what I did wrong with my functor and
> hopefully learn something from your replies.

You want std::find_if not std::find.

/Leigh

[toc] | [prev] | [next] | [standalone]


#8191

FromFencer <no.i.dont@want.mail.from.spammers.invalid>
Date2011-07-25 13:40 +0200
Message-ID<99531oF7qbU1@mid.individual.net>
In reply to#8190
On 2011-07-25 13:38, Leigh Johnston wrote:
>
> You want std::find_if not std::find.

Ah, so simple! Thanks Leigh!

- Fencer

>
> /Leigh

[toc] | [prev] | [next] | [standalone]


#8197

FromSaeed Amrollahi <amrollahi.saeed@gmail.com>
Date2011-07-25 05:14 -0700
Message-ID<45e0fa70-4d95-4b0a-bd68-6373efc649d1@bl1g2000vbb.googlegroups.com>
In reply to#8189
On Jul 25, 2:25 pm, Fencer <no.i.d...@want.mail.from.spammers.invalid>
wrote:
> Hello, I am very rusty in C++ and I'm having some problems: I have a
> std::set<SomeClass> and I need to look through the set to find if any of
> the instances of SomeClass that it contains has a particular value for
> one of its data members. I know I could simply iterate through the set
> myself and check every SomeClass instance if any of them is a match, but
> I tried to do it using functors instead.
> The following simplified test program does not build, and it seems to be
> that operator== is missing for the struct s1. Could you gurus help me
> explain why my test program does not build and how I should fix it?
>
> #include <algorithm>
> #include <functional>
> #include <set>
>
> using namespace std;
>
> struct s1
> {
>     s1(int u, int v) : u(u), v(v) {}
>
>     int u, v;
>
> };
>
> struct OnV : public unary_function<s1, bool>
> {
>     explicit OnV(int v) : v(v) {}
>
>     bool operator()(s1 const& inst) const
>     {
>        return v == inst.v;
>     }
>
>     int v;
>
> };
>
> int main()
> {
>     set<s1> a_set;
>
>     find(a_set.begin(), a_set.end(), OnV(4711));
>
> }
>
> $ g++ -Wall -Wextra -std=c++98 -pedantic functor.cpp -o functor.exe
> /usr/lib/gcc/i686-pc-cygwin/4.3.4/include/c++/bits/stl_algo.h: In
> function ‘_InputIterator std::__find(_InputIterator, _InputIterator,
> const _Tp&, std::input_iterator_tag) [with _InputIterator =
> std::_Rb_tree_const_iterator<s1>, _Tp = OnV]’:
> /usr/lib/gcc/i686-pc-cygwin/4.3.4/include/c++/bits/stl_algo.h:3814:
> instantiated from ‘_IIter std::find(_IIter, _IIter, const _Tp&) [with
> _IIter = std::_Rb_tree_const_iterator<s1>, _Tp = OnV]’
> functor.cpp:30:   instantiated from here
> /usr/lib/gcc/i686-pc-cygwin/4.3.4/include/c++/bits/stl_algo.h:151:
> error: no match for ‘operator==’ in
> ‘__first.std::_Rb_tree_const_iterator<_Tp>::operator* [with _Tp = s1]()
> == __val’
>
> Thank you for reading and thanks for any help! Even though I could use
> the alternative solution I mentioned above that does not involve
> functors, I wanted to know what I did wrong with my functor and
> hopefully learn something from your replies.
>
> - Fencer

Hi

You need to special function objects called predicate
and find_if generic function:

struct Pair
{
 Pair(int u, int v) : u(u), v(v) {}
 int u, v;
};

// Just for illustration: Somehow inkorect and incomplt
// Set relies on a comparison operation (by default <)
bool operator<(const Pair& p1, const Pair& p2)
{
  return (p1.u < p2.u && p1.v < p2.v) ? true : false;
}

struct CheckV { // predicate
  explicit CheckV(int v) : v(v) {}
  bool operator()(Pair const& inst) const
  {
     return v == inst.v;
  }
  int v;
};

struct CheckU { // predicate
  explicit CheckU(int u) : u(u) {}
  bool operator()(Pair const& inst) const
  {
     return u == inst.u;
  }
  int u;
};

#include <set>
#include <algorithm>
#include <iostream>

int main()
{
  using namespace std;
  set<Pair> MySet;
  MySet.insert(Pair(0, 1));
  MySet.insert(Pair(1, 2));
  MySet.insert(Pair(2, 4711));

  set<Pair>::const_iterator cit =
        find_if(MySet.begin(), MySet.end(), CheckV(4711));
  if (cit != MySet.end())
   cout << "(" << cit->u << ", " << cit->v << ")\n";

  return 0;
}

HTH,
  -- Saeed Amrollahi

[toc] | [prev] | [next] | [standalone]


#8199

FromLeigh Johnston <leigh@i42.co.uk>
Date2011-07-25 13:52 +0100
Message-ID<9_idnZwm9KOc-rDTnZ2dnUVZ8tudnZ2d@giganews.com>
In reply to#8197
On 25/07/2011 13:14, Saeed Amrollahi wrote:
> On Jul 25, 2:25 pm, Fencer<no.i.d...@want.mail.from.spammers.invalid>
> wrote:
[snip]
> // Just for illustration: Somehow inkorect and incomplt
> // Set relies on a comparison operation (by default<)
> bool operator<(const Pair&  p1, const Pair&  p2)
> {
>    return (p1.u<  p2.u&&  p1.v<  p2.v) ? true : false;
> }
>

perhaps you meant:

	return p1.u < p2.u || (p1.u == p2.u && p1.v < p2.v);

"? true : false" is superfluous BTW.

[snip]

/Leigh

[toc] | [prev] | [next] | [standalone]


#8202

FromSaeed Amrollahi <amrollahi.saeed@gmail.com>
Date2011-07-25 06:46 -0700
Message-ID<3a362897-54f7-42f3-9984-3feb5a47169f@g2g2000vbl.googlegroups.com>
In reply to#8199
On Jul 25, 3:52 pm, Leigh Johnston <le...@i42.co.uk> wrote:
> On 25/07/2011 13:14, Saeed Amrollahi wrote:
>
> > On Jul 25, 2:25 pm, Fencer<no.i.d...@want.mail.from.spammers.invalid>
> > wrote:
> [snip]
> > // Just for illustration: Somehow inkorect and incomplt
> > // Set relies on a comparison operation (by default<)
> > bool operator<(const Pair&  p1, const Pair&  p2)
> > {
> >    return (p1.u<  p2.u&&  p1.v<  p2.v) ? true : false;
> > }
>
> perhaps you meant:
>
>         return p1.u < p2.u || (p1.u == p2.u && p1.v < p2.v);
>
> "? true : false" is superfluous BTW.
>
> [snip]
>
> /Leigh

May be. I just want to say for using set and its insert operation
we should have operator function <.
About your implementation, I guess it depends to
exact meaning of pair. pair as a point
is different from pair as an numbers interval.

Cheers,
  -- Saeed Amrollahi
for example

[toc] | [prev] | [next] | [standalone]


#8205

FromLeigh Johnston <leigh@i42.co.uk>
Date2011-07-25 15:00 +0100
Message-ID<sY6dnXDmh76F6rDTnZ2dnUVZ7tqdnZ2d@giganews.com>
In reply to#8202
On 25/07/2011 14:46, Saeed Amrollahi wrote:
> On Jul 25, 3:52 pm, Leigh Johnston<le...@i42.co.uk>  wrote:
>> On 25/07/2011 13:14, Saeed Amrollahi wrote:
>>
>>> On Jul 25, 2:25 pm, Fencer<no.i.d...@want.mail.from.spammers.invalid>
>>> wrote:
>> [snip]
>>> // Just for illustration: Somehow inkorect and incomplt
>>> // Set relies on a comparison operation (by default<)
>>> bool operator<(const Pair&    p1, const Pair&    p2)
>>> {
>>>     return (p1.u<    p2.u&&    p1.v<    p2.v) ? true : false;
>>> }
>>
>> perhaps you meant:
>>
>>          return p1.u<  p2.u || (p1.u == p2.u&&  p1.v<  p2.v);
>>
>> "? true : false" is superfluous BTW.
>>
>> [snip]
>>
>> /Leigh
>
> May be. I just want to say for using set and its insert operation
> we should have operator function<.
> About your implementation, I guess it depends to
> exact meaning of pair. pair as a point
> is different from pair as an numbers interval.

Your version doesn't work; mine does.  In your version (1, 2) is 
equivalent to (1, 3) and (1, 2) is equivalent to (2, 1); this is plainly 
wrong.  Hint: (a == b) is the same as !(a < b) && !(b < a).

/Leigh

[toc] | [prev] | [next] | [standalone]


#8208

FromSaeed Amrollahi <amrollahi.saeed@gmail.com>
Date2011-07-25 07:27 -0700
Message-ID<b6ab2951-7570-4365-becb-9fd8b104cb36@y13g2000yqy.googlegroups.com>
In reply to#8205
On Jul 25, 5:00 pm, Leigh Johnston <le...@i42.co.uk> wrote:
> On 25/07/2011 14:46, Saeed Amrollahi wrote:
>
>
>
>
>
>
>
>
>
> > On Jul 25, 3:52 pm, Leigh Johnston<le...@i42.co.uk>  wrote:
> >> On 25/07/2011 13:14, Saeed Amrollahi wrote:
>
> >>> On Jul 25, 2:25 pm, Fencer<no.i.d...@want.mail.from.spammers.invalid>
> >>> wrote:
> >> [snip]
> >>> // Just for illustration: Somehow inkorect and incomplt
> >>> // Set relies on a comparison operation (by default<)
> >>> bool operator<(const Pair&    p1, const Pair&    p2)
> >>> {
> >>>     return (p1.u<    p2.u&&    p1.v<    p2.v) ? true : false;
> >>> }
>
> >> perhaps you meant:
>
> >>          return p1.u<  p2.u || (p1.u == p2.u&&  p1.v<  p2.v);
>
> >> "? true : false" is superfluous BTW.
>
> >> [snip]
>
> >> /Leigh
>
> > May be. I just want to say for using set and its insert operation
> > we should have operator function<.
> > About your implementation, I guess it depends to
> > exact meaning of pair. pair as a point
> > is different from pair as an numbers interval.
>
> Your version doesn't work; mine does.  In your version (1, 2) is
> equivalent to (1, 3) and (1, 2) is equivalent to (2, 1); this is plainly
> wrong.  Hint: (a == b) is the same as !(a < b) && !(b < a).
>
> /Leigh

Yes. You are right.
I really didn't think a lot about my implementation
as I mentioned in the comment.

Regards,
  -- Saeed Amrollahi

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.c++


csiph-web