-
STL related
i am trying to use some of the algorithms in STL , and i have problems making my class "STL-compliant". I defined the proper operators, but i get compile errors i am not able to get past when i try to use sort. any ideas about what i am making wrong?
Code:
#include <algorithm>
#include <vector.h>
class IPoint
{
public :
float energ,x,y,z;
char nume[10];
IPoint(); //no arg constructor
IPoint(const IPoint& m); //copy constructor
const IPoint& operator=(const IPoint& right); //copy assignment operator
IPoint(float, float, float, float, char*);
void Set(float, float, float, float, char*);
bool operator==( const IPoint& right) ; //== operator
bool operator!=(const IPoint& right) ; //!= operator
bool operator<(const IPoint& right) ; //< operator
bool operator>(const IPoint& right) ; //> operator
};
IPoint::IPoint()
{
Set(0,0,0,0,"defname");
}
IPoint::IPoint(float en,float vx,float vy, float vz,char* a)
{
Set(en,vx,vy,vz,a);
}
void IPoint::Set(float en,float vx,float vy, float vz,char *vnume)
{
energ=en;
x=vx;
y=vy;
z=vz;
strcpy(nume,vnume);
}
IPoint::IPoint(const IPoint& p ){
energ=p.energ;
x=p.x;
y=p.y;
z=p.z;
strcpy(nume,p.nume);
};
const IPoint& IPoint::operator=(const IPoint& right){
if(this!=&right){
IPoint(right);
};
return *this;
};
bool IPoint::operator==( const IPoint& right){
return (energ == right.energ);
};
bool IPoint::operator!=(const IPoint& right){
return (energ!=right.energ);
};
bool IPoint::operator>(const IPoint& right){
return (energ>right.energ);
};
bool IPoint::operator<(const IPoint& right){
return (energ<right.energ);
};
int main(){
vector<IPoint> vect;
IPoint pct;
pct.Set(100,0,0,0,"1");
vect.push_back(pct);
pct.Set(150,0,0,0,"1");
vect.push_back(pct);
pct.Set(250,0,0,0,"2");
vect.push_back(pct);
if (vect[0]<vect[1]) cout<<"0<1"<<endl;
sort(vect.begin(),vect.end());
};
-
Change:
Code:
#include <algorithm>
#include <vector.h>
to:
Code:
#include <algorithm>
#include <vector>
#include <iostream>
using namespace std;
If that doesn't work, post the errors you are getting and the compiler you are using.
-
thank you for looking at it. tried what you said and it does not work.
here are the errors and the compiler:
Code:
[]$ g++ test2.cpp
/usr/lib/gcc/i586-mandrake-linux-gnu/3.4.3/../../../../include/c++/3.4.3/bits/stl_algo.h: In function `const _Tp& std::__median(const _Tp&, const _Tp&, const _Tp&) [with _Tp = IPoint]':
/usr/lib/gcc/i586-mandrake-linux-gnu/3.4.3/../../../../include/c++/3.4.3/bits/stl_algo.h:2482: instantiated from `void std::__introsort_loop(_RandomAccessIterator, _RandomAccessIterator, _Size) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<IPoint*, std::vector<IPoint, std::allocator<IPoint> > >, _Size =int]'
/usr/lib/gcc/i586-mandrake-linux-gnu/3.4.3/../../../../include/c++/3.4.3/bits/stl_algo.h:2553: instantiated from `void std::sort(_RandomAccessIterator, _RandomAccessIterator) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<IPoint*, std::vector<IPoint, std::allocator<IPoint> > >]'
test2.cpp:90: instantiated from here
/usr/lib/gcc/i586-mandrake-linux-gnu/3.4.3/../../../../include/c++/3.4.3/bits/stl_algo.h:90: error: passing `const IPoint' as `this' argument of `bool IPoint::operator<(const IPoint&)' discards qualifiers
/usr/lib/gcc/i586-mandrake-linux-gnu/3.4.3/../../../../include/c++/3.4.3/bits/stl_algo.h:91: error: passing `const IPoint' as `this' argument of `bool IPoint::operator<(const IPoint&)' discards qualifiers
/usr/lib/gcc/i586-mandrake-linux-gnu/3.4.3/../../../../include/c++/3.4.3/bits/stl_algo.h:93: error: passing `const IPoint' as `this' argument of `bool IPoint::operator<(const IPoint&)' discards qualifiers
/usr/lib/gcc/i586-mandrake-linux-gnu/3.4.3/../../../../include/c++/3.4.3/bits/stl_algo.h:97: error: passing `const IPoint' as `this' argument of `bool IPoint::operator<(const IPoint&)' discards qualifiers
/usr/lib/gcc/i586-mandrake-linux-gnu/3.4.3/../../../../include/c++/3.4.3/bits/stl_algo.h:99: error: passing `const IPoint' as `this' argument of `bool IPoint::operator<(const IPoint&)' discards qualifiers
[]$ g++ -v
Reading specs from /usr/lib/gcc/i586-mandrake-linux-gnu/3.4.3/specs
Configured with: ../configure --prefix=/usr --libexecdir=/usr/lib --with-slibdir=/lib --mandir=/usr/share/man --infodir=/usr/share/info --enable-shared --enable-threads=posix --disable-checking --enable-long-long --enable-__cxa_atexit --enable-clocale=gnu --disable-libunwind-exceptions --enable-languages=c,c++,ada,f77,objc,java --host=i586-mandrake-linux-gnu --with-system-zlib
Thread model: posix
gcc version 3.4.3 (Mandrakelinux 10.2 3.4.3-7mdk)
-
From the text of the error, I think what's happening (though you'd have to consult the implementation of std::sort to be sure!) is that the algorithm is calling your operator< in a way you didn't anticipate, causing the error. Try defining operator< as a free (friend) function:
Code:
class IPoint
{
//All the rest as before, except operator<
friend operator<(const IPoint&, const IPoint&);
};
bool operator<(const IPoint& lhs, const IPoint& rhs){
return (lhs.energ < rhs.energ);
}
Also, a couple of side notes:
1. If you implement != and > as negation of == and <, you'll save on duplicate code.
2. You really should make your data members private.
3. PLEASE, if there's no other reason forcing you not to, make nume a std::string instead of a char[].
-
It seems that the g++ implementation of std::sort makes the objects const before passing them to the < operator. This causes a conflict because your operator overload functions are not marked as const. To fix this, you will have to mark these functions const. A const member function is a member function that does not change its object.
Code:
#include <algorithm>
#include <vector>
#include <iostream>
using namespace std;
class IPoint
{
public :
float energ,x,y,z;
char nume[10];
IPoint(); //no arg constructor
IPoint(const IPoint& m); //copy constructor
const IPoint& operator=(const IPoint& right); //copy assignment operator
IPoint(float, float, float, float, char*);
void Set(float, float, float, float, char*);
bool operator==( const IPoint& right) const; //== operator
bool operator!=(const IPoint& right) const; //!= operator
bool operator<(const IPoint& right) const; //< operator
bool operator>(const IPoint& right) const; //> operator
};
IPoint::IPoint()
{
Set(0,0,0,0,"defname");
}
IPoint::IPoint(float en,float vx,float vy, float vz,char* a)
{
Set(en,vx,vy,vz,a);
}
void IPoint::Set(float en,float vx,float vy, float vz,char *vnume)
{
energ=en;
x=vx;
y=vy;
z=vz;
strcpy(nume,vnume);
}
IPoint::IPoint(const IPoint& p ){
energ=p.energ;
x=p.x;
y=p.y;
z=p.z;
strcpy(nume,p.nume);
};
const IPoint& IPoint::operator=(const IPoint& right){
if(this!=&right){
IPoint(right);
};
return *this;
};
bool IPoint::operator==( const IPoint& right) const{
return (energ == right.energ);
};
bool IPoint::operator!=(const IPoint& right) const{
return (energ!=right.energ);
};
bool IPoint::operator>(const IPoint& right) const{
return (energ>right.energ);
};
bool IPoint::operator<(const IPoint& right) const{
return (energ<right.energ);
};
-
i added the const to the operator overloaded functions and i finally got it to compile and run without errors.
the problem is that the sort algorithm is not sorting the vector. my blind guess is that it might have something to do with the way i defined the constructors, that makes it impossible for the algorithm to switch two elements in the vector, but i completlly get lost when i am trying to debug inside "sort()".
-
Code:
const IPoint& IPoint::operator=(const IPoint& right){
if(this!=&right){
IPoint(right);
};
return *this;
};
Your assigment operator is wrong. The line IPoint(right); simply creates a temporary IPoint object that is destroyed at the end of the statement. The code in your assignment operator should be similar to the code in your copy constructor. Here is an article.
-
thank you very much for your help. it works now.