Compilation error for template class - c++

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

Related

unordered_map from own type by overloading operator() fails

What's wrong with the operator() inside Entity (hasher) ?
Copy-pasting it to a separate struct works :
#include <bitset>
#include <unordered_map>
using namespace std;
struct Entity {
string name;
size_t operator()(const Entity& k) const noexcept
{ return std::hash<string>{}(k.name); }
bool operator== (const Entity& e) const noexcept
{ return e.name == name; }
};
struct KeyHasher {
size_t operator()(const Entity& k) const noexcept
{ return std::hash<string>{}(k.name); }
};
int main(){
// unordered_map<const Entity, bitset<24>, KeyHasher> m1; // OK
unordered_map<const Entity, bitset<24>> m2; // unordered_map() ill-formed ?
return 0;
}
Error :
<source>: In function 'int main()':
<source>:25:43: error: use of deleted function 'std::unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map()
[with _Key = const Entity; _Tp = std::bitset<24>; _Hash = std::hash<const Entity>; _Pred = std::equal_to<const Entity>; _Alloc = std::allocator<std::pair<const Entity, std::bitset<24> > >]'
25 | unordered_map<const Entity, bitset<24>> m2;
| ^~
In file included from /opt/compiler-explorer/gcc-cxx-modules-trunk-20220427/include/c++/11.0.0/unordered_map:47,
from <source>:3:
/opt/compiler-explorer/gcc-cxx-modules-trunk-20220427/include/c++/11.0.0/bits/unordered_map.h:141:7: note: 'std::unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map() [with _Key = const Entity; _Tp = std::bitset<24>; _Hash = std::hash<const Entity>; _Pred = std::equal_to<const Entity>; _Alloc = std::allocator<std::pair<const Entity, std::bitset<24> > >]'
is implicitly deleted because the default definition would be ill-formed:
141 | unordered_map() = default;
run
If you don't specify a hash function for your map it defaults to std::hash<Key> with your key type.
So you will need to define this specialization of std::hash
template<>
struct std::hash<const Entity>
{
std::size_t operator()(const Entity const& k) const noexcept
{
return std::hash<string>{}(k.name);
}
}

Unusual compiler message in gcc-8.2

The following piece of code works as expected but gives an odd looking message during compilation. Not sure what to make of it, but just trying to understand what GCC is trying to convey. Is it an error or just a GCC oddity? This is not happening in gcc-10.2
#include <algorithm>
#include <array>
#include <stdexcept>
#include <optional>
template < typename T >
struct Optional : public std::optional < T >
{
using impl_t = std::optional < T >;
using impl_t::impl_t;
constexpr inline friend bool operator == (Optional const & lhs, Optional const & rhs)
{
return static_cast < impl_t const & >(lhs) == static_cast < impl_t const & >(rhs);
}
template < typename U, typename = std::enable_if_t < std::is_convertible_v < U, T > > >
constexpr inline friend bool operator == (const Optional& lhs, U const & rhs)
{
return lhs.has_value() && static_cast < impl_t const & >(lhs) == rhs;
}
};
[[maybe_unused]]
auto triggers_unusual_compile_warning()
{
constexpr std::array < Optional < int32_t >, 4 > c{{1, 2, 3, std::nullopt}};
if (std::count(c.begin(), c.end(), std::nullopt) != 1)
throw std::runtime_error("WTH!!!");
};
int main()
{
triggers_unusual_compile_warning();
}
That small program triggers the following message
/opt/compiler-explorer/gcc-8.2.0/include/c++/8.2.0/bits/predefined_ops.h: In instantiation of 'bool __gnu_cxx::__ops::_Iter_equals_val<_Value>::operator()(_Iterator) [with _Iterator = const Optional<int>*; _Value = const std::nullopt_t]':
/opt/compiler-explorer/gcc-8.2.0/include/c++/8.2.0/bits/stl_algo.h:3194:12: required from 'typename std::iterator_traits<_Iterator>::difference_type std::__count_if(_InputIterator, _InputIterator, _Predicate) [with _InputIterator = const Optional<int>*; _Predicate = __gnu_cxx::__ops::_Iter_equals_val<const std::nullopt_t>; typename std::iterator_traits<_Iterator>::difference_type = long int]'
/opt/compiler-explorer/gcc-8.2.0/include/c++/8.2.0/bits/stl_algo.h:4082:29: required from 'typename std::iterator_traits<_Iterator>::difference_type std::count(_IIter, _IIter, const _Tp&) [with _IIter = const Optional<int>*; _Tp = std::nullopt_t; typename std::iterator_traits<_Iterator>::difference_type = long int]'
<source>:29:52: required from here
/opt/compiler-explorer/gcc-8.2.0/include/c++/8.2.0/optional:1371:5: note: candidate 1: 'constexpr bool std::operator==(const std::optional<_Tp>&, std::nullopt_t) [with _Tp = int]'
operator==(const optional<_Tp>& __lhs, nullopt_t) noexcept
^~~~~~~~
<source>:12:34: note: candidate 2: 'constexpr bool operator==(const Optional<int>&, const Optional<int>&)'
constexpr inline friend bool operator == (Optional const & lhs, Optional const & rhs)
^~~~~~~~
ASM generation compiler returned: 0
In file included from <source>:4:
/opt/compiler-explorer/gcc-8.2.0/include/c++/8.2.0/bits/predefined_ops.h: In instantiation of 'bool __gnu_cxx::__ops::_Iter_equals_val<_Value>::operator()(_Iterator) [with _Iterator = const Optional<int>*; _Value = const std::nullopt_t]':
/opt/compiler-explorer/gcc-8.2.0/include/c++/8.2.0/bits/stl_algo.h:3194:12: required from 'typename std::iterator_traits<_Iterator>::difference_type std::__count_if(_InputIterator, _InputIterator, _Predicate) [with _InputIterator = const Optional<int>*; _Predicate = __gnu_cxx::__ops::_Iter_equals_val<const std::nullopt_t>; typename std::iterator_traits<_Iterator>::difference_type = long int]'
/opt/compiler-explorer/gcc-8.2.0/include/c++/8.2.0/bits/stl_algo.h:4082:29: required from 'typename std::iterator_traits<_Iterator>::difference_type std::count(_IIter, _IIter, const _Tp&) [with _IIter = const Optional<int>*; _Tp = std::nullopt_t; typename std::iterator_traits<_Iterator>::difference_type = long int]'
<source>:29:52: required from here
/opt/compiler-explorer/gcc-8.2.0/include/c++/8.2.0/optional:1371:5: note: candidate 1: 'constexpr bool std::operator==(const std::optional<_Tp>&, std::nullopt_t) [with _Tp = int]'
operator==(const optional<_Tp>& __lhs, nullopt_t) noexcept
^~~~~~~~
<source>:12:34: note: candidate 2: 'constexpr bool operator==(const Optional<int>&, const Optional<int>&)'
constexpr inline friend bool operator == (Optional const & lhs, Optional const & rhs)
^~~~~~~~
Execution build compiler returned: 0
The problem with the code is that the equality operator is ambiguous. A std::nullopt can be converted to a std::optional.
So, by instantiating a operator== when you call std::count, the compiler cannot choose between the operator== from the library and your operator== declared as
constexpr inline friend bool operator == (Optional const & lhs, Optional const & rhs)
How exactly to solve this problem depends on the details you have in mind. For example, if you add an explicit comparison with std::nullopt_t
constexpr inline friend bool operator == (Optional const & lhs, std::nullopt_t const & rhs)
{
return static_cast < impl_t const & >(lhs) == static_cast < impl_t const & >(rhs);
}
you force the compiler to choose your more-specific implementation, and the error disappears.
But of course, a good solution depends on what you have in mind.

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.

Strange "invalid initialization of non-const reference" when using templates

I got the following error:
Database.hpp: In member function ‘Table<T, S>& Table<T, S>::operator=(const Table<T, S>&) [with T = int, int S = 3, Table<T, S> = Table<int, 3>]’:
Database.hpp:40:8: instantiated from ‘void std::vector<_Tp, _Alloc>::_M_insert_aux(std::vector<_Tp, _Alloc>::iterator, const _Tp&) [with _Tp = List, _Alloc = std::allocator<List>, std::vector<_Tp, _Alloc>::iterator = __gnu_cxx::__normal_iterator<List*, std::vector<List> >, typename std::_Vector_base<_Tp, _Alloc>::_Tp_alloc_type::pointer = List*]’
/usr/include/c++/4.6/bits/stl_vector.h:834:4: instantiated from ‘void std::vector<_Tp, _Alloc>::push_back(const value_type&) [with _Tp = List, _Alloc = std::allocator<List>, std::vector<_Tp, _Alloc>::value_type = List]’
SelectiveReading.hpp:139:34: instantiated from here
Database.hpp:34:16: error: invalid initialization of non-const reference of type ‘Table<int, 3>&’ from an rvalue of type ‘Table<int, 3>* const’
I have the following ADTs. I don't get it what is wrong with them.
// this is Database.hpp
template <class T, int S>
class Table
{
T tab[S];
public:
inline T& operator[](int i)
{
return tab[i];
}
inline const T& operator[](int i) const
{
return tab[i];
}
Table() {}
~Table() {}
Table(const Table &t)
{
for ( int i=0; i<S; ++i )
{
tab[i] = t[i];
}
}
Table& operator=(const Table &t)
{
for ( int i=0; i<S; ++i )
{
tab[i] = t[i];
}
return this;
}
};
typedef Table<int,3> Date;
struct List
{
Date AnnouncementDate;
int BonusShares;
int StockSplit;
int CashDividend;
bool DividendPayment;
Date ExDividendDate;
Date ShareRecordDate;
Date BonusSharesListingDate;
};
typedef std::vector<List> Database;
While the call was like:
List record;
// (...)
Data.push_back(record); // this is SelectiveReading.hpp:139:34
In the last line of your operator=, you are returning this (a pointer), when you mean to return *this (a reference).
return this; needs to be return *this;

friend/overload '<' with own class [duplicate]

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.