How to sort vector<complex<double> >

Discussion in 'C++' started by jeremit0, Jun 25, 2008.

  1. jeremit0

    jeremit0 Guest

    I'm trying to sort a vector<complex<double> > and can't figure it
    out. I recognize the problem is that there isn't a default operator<
    for complex data types. I have written my own operator and can use
    it, but std::sort doesn't seem to find it. I have copied a very
    simple example below. Everything compiles just fine when the line
    with std::sort function is commented out, but with that line included
    a whole slew of errors are given like:

    /usr/include/c++/4.0.0/bits/stl_algo.h:2996: error: no match for
    ‘operator<’ in ‘* __first2 < * __first1’

    Can someone help me?
    Thanks,
    Jeremy


    #include<iostream>
    #include<algorithm>
    #include<vector>
    #include<complex>

    using std::vector;
    using std::cout;
    using std::endl;
    using std::complex;

    inline bool operator< (complex<double>& x, complex<double>& y){
    return x.real() < y.real();
    }

    int main(){
    vector<complex<double> > values(3);
    values[0] = 9.0; values[1] = 8.0; values[2] = 7.0;
    vector<pair> Sets(values.size());

    if( values[0] < values[1] ) cout << "first" << endl;
    else cout << "second" << endl;

    std::stable_sort(values.begin(), values.end());
    return 0;
    }
     
    jeremit0, Jun 25, 2008
    #1
    1. Advertising

  2. jeremit0

    Noah Roberts Guest

    jeremit0 wrote:
    > I'm trying to sort a vector<complex<double> > and can't figure it
    > out. I recognize the problem is that there isn't a default operator<
    > for complex data types. I have written my own operator and can use
    > it, but std::sort doesn't seem to find it. I have copied a very
    > simple example below. Everything compiles just fine when the line
    > with std::sort function is commented out, but with that line included
    > a whole slew of errors are given like:
    >
    > /usr/include/c++/4.0.0/bits/stl_algo.h:2996: error: no match for
    > ‘operator<’ in ‘* __first2 < * __first1’
    >
    > Can someone help me?
    > Thanks,
    > Jeremy
    >
    >
    > #include<iostream>
    > #include<algorithm>
    > #include<vector>
    > #include<complex>
    >
    > using std::vector;
    > using std::cout;
    > using std::endl;
    > using std::complex;
    >
    > inline bool operator< (complex<double>& x, complex<double>& y){
    > return x.real() < y.real();
    > }
    >
    > int main(){
    > vector<complex<double> > values(3);
    > values[0] = 9.0; values[1] = 8.0; values[2] = 7.0;
    > vector<pair> Sets(values.size());
    >
    > if( values[0] < values[1] ) cout << "first" << endl;
    > else cout << "second" << endl;
    >
    > std::stable_sort(values.begin(), values.end());
    > return 0;
    > }
    >


    I think you'll need to place your operator in the std namespace. The
    better option would be to pass a comparator to std::sort instead of
    using the default (std::less).

    bool complex_less_pred(complex<double> const& x, complex<double> const& y)
    {
    return x.real() < y.real();
    }

    ....
    std::stable_sort(begin, end, &complex_less_pred);
     
    Noah Roberts, Jun 25, 2008
    #2
    1. Advertising

  3. jeremit0

    jeremit0 Guest

    On Jun 25, 11:21 am, Noah Roberts <> wrote:
    > jeremit0 wrote:
    > > I'm trying to sort a vector<complex<double> > and can't figure it
    > > out.  I recognize the problem is that there isn't a default operator<
    > > for complex data types.  I have written my own operator and can use
    > > it, but std::sort doesn't seem to find it.  I have copied a very
    > > simple example below.  Everything compiles just fine when the line
    > > with std::sort function is commented out, but with that line included
    > > a whole slew of errors are given like:

    >
    > > /usr/include/c++/4.0.0/bits/stl_algo.h:2996: error: no match for
    > > ‘operator<’ in ‘* __first2 < * __first1’

    >
    > > Can someone help me?
    > > Thanks,
    > > Jeremy

    >
    > > #include<iostream>
    > > #include<algorithm>
    > > #include<vector>
    > > #include<complex>

    >
    > > using std::vector;
    > > using std::cout;
    > > using std::endl;
    > > using std::complex;

    >
    > > inline bool operator< (complex<double>& x, complex<double>& y){
    > >     return x.real() < y.real();
    > > }

    >
    > > int main(){
    > >     vector<complex<double> > values(3);
    > >     values[0] = 9.0; values[1] = 8.0; values[2] = 7.0;
    > >     vector<pair> Sets(values.size());

    >
    > >     if( values[0] < values[1] ) cout << "first" << endl;
    > >     else cout << "second" << endl;

    >
    > >     std::stable_sort(values.begin(), values.end());
    > >     return 0;
    > > }

    >
    > I think you'll need to place your operator in the std namespace.  The
    > better option would be to pass a comparator to std::sort instead of
    > using the default (std::less).
    >
    > bool complex_less_pred(complex<double> const& x, complex<double> const& y)
    > {
    >    return x.real() < y.real();
    >
    > }
    >
    > ...
    > std::stable_sort(begin, end, &complex_less_pred);


    Thank you, both techniques worked well. I'm curious why the operator
    needs to be in the std namespace. Is that a requirement for the sort
    algorithm?

    Thanks again,
    Jeremy
     
    jeremit0, Jun 25, 2008
    #3
  4. jeremit0

    James Kanze Guest

    On Jun 25, 4:55 pm, jeremit0 <> wrote:
    > I'm trying to sort a vector<complex<double> > and can't figure
    > it out. I recognize the problem is that there isn't a default
    > operator< for complex data types. I have written my own
    > operator and can use it, but std::sort doesn't seem to find
    > it.


    Normal. Sort is a template function, which uses another
    template, std::less, in which the < operator is in a dependent
    expression. Which means that if it isn't found in the context
    where the template is defined, only ADL is used, and so only
    operators in the associated namespaces and classes (in this case
    std::) are found.

    > I have copied a very simple example below. Everything
    > compiles just fine when the line with std::sort function is
    > commented out, but with that line included a whole slew of
    > errors are given like:


    > /usr/include/c++/4.0.0/bits/stl_algo.h:2996: error: no match for
    > ?operator<? in ?* __first2 < * __first1?


    > Can someone help me?


    The basic problem is that you're trying to do something that
    you're not allowed to do: define an operator on a standard type
    (where it doesn't make sense). The real solution is to define
    some sort of ordering function (or functional object) yourself,
    and pass that to sort as the third argument.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, Jun 25, 2008
    #4
  5. jeremit0

    Kai-Uwe Bux Guest

    jeremit0 wrote:

    > On Jun 25, 11:21 am, Noah Roberts <> wrote:
    >> jeremit0 wrote:
    >> > I'm trying to sort a vector<complex<double> > and can't figure it
    >> > out.  I recognize the problem is that there isn't a default operator<
    >> > for complex data types.  I have written my own operator and can use
    >> > it, but std::sort doesn't seem to find it.

    [snip]
    >> I think you'll need to place your operator in the std namespace.  The
    >> better option would be to pass a comparator to std::sort instead of
    >> using the default (std::less).
    >>
    >> bool complex_less_pred(complex<double> const& x, complex<double> const&
    >> y)
    >> {
    >> return x.real() < y.real();
    >>
    >> }
    >>
    >> ...
    >> std::stable_sort(begin, end, &complex_less_pred);

    >
    > Thank you, both techniques worked well. I'm curious why the operator
    > needs to be in the std namespace. Is that a requirement for the sort
    > algorithm?


    No.

    I think, ut's a lookup thing. The template std::complex is in namespace std,
    and so are std::less and std::sort. Thus, the global namespace will not be
    searched; and operator< for complex numbers will not be found if it isn't
    in namespace std, too. (Or something like that.)


    Best

    Kai-Uwe Bux
     
    Kai-Uwe Bux, Jun 25, 2008
    #5
  6. jeremit0

    Noah Roberts Guest

    jeremit0 wrote:

    > Thank you, both techniques worked well. I'm curious why the operator
    > needs to be in the std namespace. Is that a requirement for the sort
    > algorithm?
    >


    I actually don't know. I probably should. It's got something to do
    with scope resolution, which can be weird wrt operators. Any operator
    you want to overload for an object in std:: seems to also need to be in
    that namespace if you ever use the overload through another function or
    object in std::.
     
    Noah Roberts, Jun 25, 2008
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.

Share This Page