How to sort vector<complex<double> >

J

jeremit0

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;
}
 
N

Noah Roberts

jeremit0 said:
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);
 
J

jeremit0

jeremit0 said:
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

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
 
J

James Kanze

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.
 
K

Kai-Uwe Bux

jeremit0 said:
jeremit0 said:
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
 
N

Noah Roberts

jeremit0 said:
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::.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,994
Messages
2,570,223
Members
46,813
Latest member
lawrwtwinkle111

Latest Threads

Top