friend/overload '<' with own class [duplicate] - c++

This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
Friending '>>' with own class
I'm trying to friend '<' operator with my own class but it doesn't notice me about an syntax error, but i get the fallowing compile error:
error:
**** Internal Builder is used for build ****
g++ -O0 -g3 -Wall -c -fmessage-length=0 -o main.o ..\main.cpp
In file included from c:\mingw\bin\../lib/gcc/mingw32/4.6.1/include/c++/algorithm:63:0,
from ..\main.cpp:8:
c:\mingw\bin\../lib/gcc/mingw32/4.6.1/include/c++/bits/stl_algo.h: In function '_RandomAccessIterator std::__unguarded_partition(_RandomAccessIterator, _RandomAccessIterator, const _Tp&) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<RAngle*, std::vector<RAngle> >, _Tp = RAngle]':
c:\mingw\bin\../lib/gcc/mingw32/4.6.1/include/c++/bits/stl_algo.h:2253:70: instantiated from '_RandomAccessIterator std::__unguarded_partition_pivot(_RandomAccessIterator, _RandomAccessIterator) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<RAngle*, std::vector<RAngle> >]'
c:\mingw\bin\../lib/gcc/mingw32/4.6.1/include/c++/bits/stl_algo.h:2284:54: instantiated from 'void std::__introsort_loop(_RandomAccessIterator, _RandomAccessIterator, _Size) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<RAngle*, std::vector<RAngle> >, _Size = int]'
c:\mingw\bin\../lib/gcc/mingw32/4.6.1/include/c++/bits/stl_algo.h:5330:4: instantiated from 'void std::sort(_RAIter, _RAIter) [with _RAIter = __gnu_cxx::__normal_iterator<RAngle*, std::vector<RAngle> >]'
..\main.cpp:13:24: instantiated from here
c:\mingw\bin\../lib/gcc/mingw32/4.6.1/include/c++/bits/stl_algo.h:2215:4: error: passing 'const RAngle' as 'this' argument of 'bool RAngle::operator<(RAngle)' discards qualifiers [-fpermissive]
class and overload function:
class RAngle
{
public:
int x,y,l;
int solution,prec;
RAngle(){
}
RAngle(int i,int j,int k){
x=i,y=j,l=k;
}
bool operator<(const RAngle rhs)
{
if(l < rhs.l){
return true;
}
return 0;
}
};
Were error appears(main.cpp):
void descrSort(vector <RAngle> &l){
sort(l.begin(),l.end());
reverse(l.begin(),l.end());
for(unsigned i=0; i<l.size();i++){
cout<<l[i]<<endl;
}
}

Couldn't this have been added to your last question on this subject?
bool operator<(const RAngle rhs)
should be
bool operator<(const RAngle& rhs) const
which should fix the error. It is a good habit to mark methods which do not modify state as const.

Related

using C++ std::sort with lambda comparator

I'm tryin to sort an array of objects using std::sort -
sort(convexHull.getSet(), convexHull.getSet()+convexHull.size(),
[](const Point & a, const Point & b) -> bool
{ if (a.getX() < b.getX())
return true;
else if (a.getX() == b.getX())
return a.getY() < b.getY();
else
return false;; }
);
where convexHull.getSet() returns a pointer to the beginning of an array.
as explained here.
But i'm getting a really long error from my compiler (Clion), something about my assignment operator -
#include <cmath>
#include <string>
using namespace std;
class Point
{
private:
int _x;
int _y;
double _arg;
void setArg()
{
if(sqrt(_x*_x + _y*_y) == 0)
_arg = 5;
else
_arg = _y / sqrt(_x*_x + _y*_y);
}
public:
Point () : Point(0, 0) {}
Point (const int x, const int y) : _x(x), _y(y)
{
setArg();
}
int getX () const
{ return _x; }
int getY () const
{ return _y; }
~Point () {}
Point& operator= (const Point &rval);
};
(where setArg simply computes a point angle from the positive x-axis).
i've tested the operator using this code -
Point p(5,5);
Point t(3,3);
t=p;
t.setXY(7,7);
and it seems to be working fine.
it's very long so i'll post just part of it -
In file included from /usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/algorithm:62:0,
from /cygdrive/c/Users/o/Desktop/CPP/ex1/cppex1/ex1/ConvexHull.cpp:7:
/usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/bits/stl_algo.h: In instantiation of 'void std::__insertion_sort(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = const Point*; _Compare = __gnu_cxx::__ops::_Iter_comp_iter<main()::<lambda(const Point&, const Point&)> >]':
/usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/bits/stl_algo.h:1880:25: required from 'void std::__final_insertion_sort(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = const Point*; _Compare = __gnu_cxx::__ops::_Iter_comp_iter<main()::<lambda(const Point&, const Point&)> >]'
/usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/bits/stl_algo.h:1966:31: required from 'void std::__sort(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = const Point*; _Compare = __gnu_cxx::__ops::_Iter_comp_iter<main()::<lambda(const Point&, const Point&)> >]'
/usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/bits/stl_algo.h:4729:18: required from 'void std::sort(_RAIter, _RAIter, _Compare) [with _RAIter = const Point*; _Compare = main()::<lambda(const Point&, const Point&)>]'
/cygdrive/c/Users/o/Desktop/CPP/ex1/cppex1/ex1/ConvexHull.cpp:75:5: required from here
/usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/bits/stl_algo.h:1847:17: error: passing 'const Point' as 'this' argument discards qualifiers [-fpermissive]
*__first = _GLIBCXX_MOVE(__val);
^
In file included from /cygdrive/c/Users/o/Desktop/CPP/ex1/cppex1/ex1/PointSet.h:9:0,
from /cygdrive/c/Users/o/Desktop/CPP/ex1/cppex1/ex1/ConvexHull.cpp:4:
/cygdrive/c/Users/o/Desktop/CPP/ex1/cppex1/ex1/Point.h:45:12: note: in call to 'Point& Point::operator=(const Point&)'
this might also be relevant -
/usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/bits/predefined_ops.h:123:46: note: candidate: bool (*)(Point&, Point&) <conversion>
/usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/bits/predefined_ops.h:123:46: note: conversion of argument 3 would be ill-formed:
/usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/bits/predefined_ops.h:123:46: error: binding 'const Point' to reference of type 'Point&' discards qualifiers
/cygdrive/c/Users/o/Desktop/CPP/ex1/cppex1/ex1/ConvexHull.cpp:68:38: note: candidate: main()::<lambda(Point&, Point&)> <near match>
[](Point & a, Point & b) -> bool
Apparently the problem is not in the comparison but in what you are passing to std::sort. What is the declaration for
convexHull.getSet()
?
If that for example returns a const Point * then you have a const correctness problem because std::sort needs to be able to write to rearrange elements.

Compilation error for template class

I'm beginer in templates and cann't resolve one compiler issue. The problem is in the following:
I have two classes.
class TMessage
{
public:
int Priority;
TMessageType Type;
bool operator> (const TMessage& m)
{
return m.Priority > Priority;
}
bool operator< (const TMessage& m)
{
return m.Priority < Priority;
}
};
template<typename T> class TMessageQueue
{
public:
T* Buffer;
int QueueStartOffset;
void SortMessages(int putPointer)
{
std::sort(Buffer+QueueStartOffset,Buffer+ putPointer);
}
};
In file included from /usr/include/c++/4.8/algorithm:62:0,
from TMessageQueue.h:2,
from TWriterThread.h:2,
from TWriterThread.cpp:1:
/usr/include/c++/4.8/bits/stl_algo.h: In instantiation of ‘_RandomAccessIterator std::__unguarded_partition(_RandomAccessIterator, _RandomAccessIterator, const _Tp&) [with _RandomAccessIterator = TMessage*; _Tp = TMessage]’:
/usr/include/c++/4.8/bits/stl_algo.h:2283:70: required from ‘_RandomAccessIterator std::__unguarded_partition_pivot(_RandomAccessIterator, _RandomAccessIterator) [with _RandomAccessIterator = TMessage*]’
/usr/include/c++/4.8/bits/stl_algo.h:2315:54: required from ‘void std::__introsort_loop(_RandomAccessIterator, _RandomAccessIterator, _Size) [with _RandomAccessIterator = TMessage*; _Size = long int]’
/usr/include/c++/4.8/bits/stl_algo.h:5461:36: required from ‘void std::sort(_RAIter, _RAIter) [with _RAIter = TMessage*]’
TMessageQueue.h:158:60: required from ‘void TMessageQueue::SortMessages(int) [with T = TMessage]’
TMessageQueue.h:143:26: required from ‘TRetCode TMessageQueue::Put(T&) [with T = TMessage]’
TWriterThread.cpp:59:34: required from here
/usr/include/c++/4.8/bits/stl_algo.h:2245:19: error: passing ‘const TMessage’ as ‘this’ argument of ‘bool TMessage::operator<(const TMessage&)’ discards qualifiers [-fpermissive]
while (__pivot < *__last)
^
make: *** [all] Error 1
What is the problem? Used compiler g++.
The operator< and operator> methods need to be const
bool operator> (const TMessage& m) const { ... }
bool operator< (const TMessage& m) const { ... }
In addition the first answer by simpel01,
this bad code:
bool operator> (const TMessage& m)
{
return m.Priority > Priority;
}
bool operator< (const TMessage& m)
{
return m.Priority < Priority;
}
In operator > must return this->Priority > m.Priority not m.Priority > this->Priority because operator > activated by object this and actually you want to say if I'm (object this) big than from m.
what you do is reverse!
and fix operator < to this->Priority < m.Priority

C++ std::sort a vector of share_ptr<objects>

How can I sort a vector of shared_ptrs C++? I'm trying to sort a vector a share_ptrs of struct data object. And the comparator function is also defined.
struct data{
int number;
};
bool comparator(const std::shared_ptr<data> &a, const std::shared_ptr<data> &b) {
return a->number < b->number();
}
int main() {
std::vector<std::shared_ptr<data>> v;
std::sort(v.begin(), v.end(), comparator);
}
But I got compile error:
In file included from /usr/include/c++/4.8/algorithm:62:0,
from test.cpp:10:
/usr/include/c++/4.8/bits/stl_algo.h: In instantiation of ‘void std::__insertion_sort(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<std::shared_ptr<data>*, std::vector<std::shared_ptr<data> > >; _Compare = bool (*)(const A&, const A&)]’:
/usr/include/c++/4.8/bits/stl_algo.h:2226:70: required from ‘void std::__final_insertion_sort(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<std::shared_ptr<data>*, std::vector<std::shared_ptr<data> > >; _Compare = bool (*)(const A&, const A&)]’
/usr/include/c++/4.8/bits/stl_algo.h:5491:55: required from ‘void std::sort(_RAIter, _RAIter, _Compare) [with _RAIter = __gnu_cxx::__normal_iterator<std::shared_ptr<data>*, std::vector<std::shared_ptr<data> > >; _Compare = bool (*)(const A&, const A&)]’
test.cpp:110:45: required from here
/usr/include/c++/4.8/bits/stl_algo.h:2159:29: error: invalid initialization of reference of type ‘const A&’ from expression of type ‘std::shared_ptr<data>’
.....
return a->number < b->number();
Must be:
return a->number < b->number;
However, I wonder if this is your real code and which compiler you are using. You should get much clearer error messages, for example:
Visual C++ 2013:
error C2064: term does not evaluate to a function taking 0 arguments
GCC v4.8.3:
error: expression cannot be used as a function
return a->number < b->number();
^
P.S.: You should post your complete code with all #includes when asking such questions. In your case, <vector>, <algorithm> and <memory>.

gcc compile-time error sorting vector in a namespace

The following MWE fails to compile on (Cygwin) gcc 4.8.3 but compiles on MSCV 2010
#include <vector>
#include <algorithm>
namespace Namespace
{
struct Bar
{
};
bool barComparator( Bar& bar1 , Bar& bar2 )
{
return true;
}
struct Foo
{
void doStuff()
{
std::vector<Bar> barVec;
std::sort( barVec.begin() , barVec.end() , barComparator );
}
};
}
int main()
{
};
gcc error message
In file included from /usr/lib/gcc/i686-pc-cygwin/4.8.3/include/c++/algorithm:62:0,
from Test007.cpp:2:
/usr/lib/gcc/i686-pc-cygwin/4.8.3/include/c++/bits/stl_algo.h: In instantiation of ‘_RandomAccessIterator std::__unguarded_partition(_RandomAccessIterator, _RandomAccessIterator, const _Tp&, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<Namespace::Bar*, std::vector<Namespace::Bar> >; _Tp = Namespace::Bar; _Compare = bool (*)(Namespace::Bar&, Namespace::Bar&)]’:
/usr/lib/gcc/i686-pc-cygwin/4.8.3/include/c++/bits/stl_algo.h:2296:78: required from ‘_RandomAccessIterator std::__unguarded_partition_pivot(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<Namespace::Bar*, std::vector<Namespace::Bar> >; _Compare = bool (*)(Namespace::Bar&, Namespace::Bar&)]’
/usr/lib/gcc/i686-pc-cygwin/4.8.3/include/c++/bits/stl_algo.h:2337:62: required from ‘void std::__introsort_loop(_RandomAccessIterator, _RandomAccessIterator, _Size, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<Namespace::Bar*, std::vector<Namespace::Bar> >; _Size = int; _Compare = bool (*)(Namespace::Bar&, Namespace::Bar&)]’
/usr/lib/gcc/i686-pc-cygwin/4.8.3/include/c++/bits/stl_algo.h:5490:44: required from ‘void std::sort(_RAIter, _RAIter, _Compare) [with _RAIter = __gnu_cxx::__normal_iterator<Namespace::Bar*, std::vector<Namespace::Bar> >; _Compare = bool (*)(Namespace::Bar&, Namespace::Bar&)]’
Test007.cpp:20:61: required from here
/usr/lib/gcc/i686-pc-cygwin/4.8.3/include/c++/bits/stl_algo.h:2263:35: error: invalid initialization of reference of type ‘Namespace::Bar&’ from expression of type ‘const Namespace::Bar’
while (__comp(*__first, __pivot))
^
/usr/lib/gcc/i686-pc-cygwin/4.8.3/include/c++/bits/stl_algo.h:2266:34: error: invalid initialization of reference of type ‘Namespace::Bar&’ from expression of type ‘const Namespace::Bar’
while (__comp(__pivot, *__last))
I'd appreciate help on figuring this one out.
The std::sort reference says that the comparator function does not require const & reference arguments, but still must not modify the arguments.
It looks like your compiler is being a bit more restrictive and requiring
bool barComparator( const Bar& bar1 , const Bar& bar2 ).

compilation error ::vector ::iteratator

I encounter this error whenever I compile my prg..
c:\mingw\bin\../lib/gcc/mingw32/4.6.2/include/c++/bits/stl_algo.h:5394:5: note: template<class _RAIter> void std::sort(_RAIter, _RAIter)
c:\mingw\bin\../lib/gcc/mingw32/4.6.2/include/c++/bits/stl_algo.h:5430:5: note: void std::sort(_RAIter, _RAIter, _Compare) [with _RAIter = __gnu_cxx::__normal_iterator<PointTwoD*, std::vector<PointTwoD> >, _Compare = bool (MissionPlan::*)(PointTwoD&, PointTwoD&)]
c:\mingw\bin\../lib/gcc/mingw32/4.6.2/include/c++/bits/stl_algo.h:5430:5: note: no known conversion for argument 3 from '<unresolved overloaded function type>' to 'bool (MissionPlan::*)(PointTwoD&, PointTwoD&)'
Below is actually my .cpp file..
bool MissionPlan::sortByCiv(const PointTwoD &t1, const PointTwoD &t2)
{
return t1.locationdata.getCivIndex() < t2.locationdata.getCivIndex();
}
void MissionPlan::topfives()
{
topfive.assign( point1.begin(), point1.end() );
sort(topfive.begin(), topfive.end(), sortByCiv);
for(int i=0; i < 5; i++)
{
topfive.at(i).displayPointdata();
}
}
missionplan.h
class MissionPlan
{
private:
int sizeofarray;
int sizeofarray2;
int xcordi;
int ycordi;
LocationData locationdata;
PointTwoD pointtwoD;
//MissionPlan missionplan;
public:
MissionPlan();
MissionPlan(int, int, float);
int getx();
int gety();
float civnum;
float getciv();
void stats();
void storedata(int, int, float);
void test();
void displayall();
void compute();
void topfives();
static bool sortByCiv(const PointTwoD &t1, const PointTwoD &t2);
};
My programme will compile and run smoothly when I remove this line from my code "sort(topfive.begin(), topfive.end(), sortByCiv);"
so is there a problem with that line of code or there other thing that is affecting it?
this is the error msg is get when i start compiling after I made sortByCiv statc and change the function para to a const..
In file included from c:\mingw\bin\../lib/gcc/mingw32/4.6.2/include/c++/algorithm:63:0,
from ..\src\/MissionPlan.h:9,
from ..\src\MissionPlanImp.cpp:3:
c:\mingw\bin\../lib/gcc/mingw32/4.6.2/include/c++/bits/stl_algo.h: In function '_RandomAccessIterator std::__unguarded_partition(_RandomAccessIterator, _RandomAccessIterator, const _Tp&, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<PointTwoD*, std::vector<PointTwoD> >, _Tp = PointTwoD, _Compare = bool (*)(PointTwoD&, PointTwoD&)]':
c:\mingw\bin\../lib/gcc/mingw32/4.6.2/include/c++/bits/stl_algo.h:2265:78: instantiated from '_RandomAccessIterator std::__unguarded_partition_pivot(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<PointTwoD*, std::vector<PointTwoD> >, _Compare = bool (*)(PointTwoD&, PointTwoD&)]'
c:\mingw\bin\../lib/gcc/mingw32/4.6.2/include/c++/bits/stl_algo.h:2306:62: instantiated from 'void std::__introsort_loop(_RandomAccessIterator, _RandomAccessIterator, _Size, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<PointTwoD*, std::vector<PointTwoD> >, _Size = int, _Compare = bool (*)(PointTwoD&, PointTwoD&)]'
c:\mingw\bin\../lib/gcc/mingw32/4.6.2/include/c++/bits/stl_algo.h:5445:4: instantiated from 'void std::sort(_RAIter, _RAIter, _Compare) [with _RAIter = __gnu_cxx::__normal_iterator<PointTwoD*, std::vector<PointTwoD> >, _Compare = bool (*)(PointTwoD&, PointTwoD&)]'
..\src\MissionPlanImp.cpp:140:48: instantiated from here
c:\mingw\bin\../lib/gcc/mingw32/4.6.2/include/c++/bits/stl_algo.h:2233:4: error: invalid initialization of reference of type 'PointTwoD&' from expression of type 'const PointTwoD'
c:\mingw\bin../lib/gcc/mingw32/4.6.2/include/c++/bits/stl_algo.h:2236:4: error: invalid initialization of reference of type 'PointTwoD&' from expression of type 'const PointTwoD'
now finally the programme gets to run on command prompt but it gets terminate with the following error msg..
"terminate called after throwing an instance of 'std::out_of_range' what(): vecotr::_M_range_check"
Thanks guys I got it up and running, thanks and appreciate for all ur helps..
The issue here is that sortByCiv is a member function, which can only be invoked relative to some receiver object (i.e. myObject.sortByCiv(...) versus sortByCiv(...). The std::sort function expects you to provide as a parameter some function that can be called as a free function with two arguments that will then produce a value.
To fix this, make sortByCiv static. This makes it no longer have a receiver object and should resolve your issue.
Hope this helps!
sortByCiv is a member function and it needs special treatment; for instance, you cant cast it to function pointer type, as it has an implicit (third) this-parameter.
And in your case, you don't need to. Just move the sortByCiv(..) out of the class declaration(or make it static), as it doesn't use this parameter:
bool sortByCiv(const PointTwoD &t1, const PointTwoD &t2)
{
return t1.locationdata.getCivIndex() < t2.locationdata.getCivIndex();
}