std::set.insert won't compile with custom class [duplicate] - c++

This question already has answers here:
problems with c++ set container
(2 answers)
Closed 9 years ago.
I have a class, Record, with three private integer fields, getters and setters, and a default and specific constructor. I intend to populate a set with Records, but am having issues getting the code to work.
#include <set>
using namespace std;
class Record
{
int a, b, c;
public:
//getters and setters
Record(){a = -1; b = -1; c = -1;};
}
int main()
{
set< Record > s;
s.insert(Record());
}
Attempting to compile results in this error:
C:\Users\Denton\Documents\Indiana University\Class Documents\Spring
2013\CSCI-H2
12\Assignment9>g++ a9.cpp -o a9
In file included from c:\mingw\bin../lib/gcc/mingw32/4.6.2/include/c++/string:5
0:0,
from c:\mingw\bin../lib/gcc/mingw32/4.6.2/include/c++/bits/loc
ale_classes.h:42,
from c:\mingw\bin../lib/gcc/mingw32/4.6.2/include/c++/bits/ios
_base.h:43,
from c:\mingw\bin../lib/gcc/mingw32/4.6.2/include/c++/ios:43,
from c:\mingw\bin../lib/gcc/mingw32/4.6.2/include/c++/ostream:
40,
from c:\mingw\bin../lib/gcc/mingw32/4.6.2/include/c++/iostream
:40,
from a9.cpp:3:
c:\mingw\bin../lib/gcc/mingw32/4.6.2/include/c++/bits/stl_function.h:
In member
function 'bool std::less<_Tp>::operator()(const _Tp&, const _Tp&) const [with _
Tp = Record]':
c:\mingw\bin../lib/gcc/mingw32/4.6.2/include/c++/bits/stl_tree.h:1267:4:
inst
antiated from 'std::pair, bool> std::_Rb_tree<_Key,
_Val, _KeyOfValue, _Compare, _Alloc>::_M_insert_unique(const _Val&) [with _Key
= Record, _Val = Record, _KeyOfValue = std::_Identity, _Compare = std::l
ess, _Alloc = std::allocator]'
c:\mingw\bin../lib/gcc/mingw32/4.6.2/include/c++/bits/stl_set.h:410:29:
insta
ntiated from 'std::pair,
_Compare, typename _Alloc::rebind<_Key>::other>::const_iterator, bool> std::set
<_Key, _Compare, _Alloc>::insert(const value_type&) [with _Key = Record, _Compar
e = std::less, _Alloc = std::allocator, typename std::_Rb_tree<_
Key, _Key, std::_Identity<_Key>, _Compare, typename _Alloc::rebind<_Key>::other>
::const_iterator = std::_Rb_tree_const_iterator, std::set<_Key, _Compare
, _Alloc>::value_type = Record]'
a9.cpp:72:28: instantiated from here
c:\mingw\bin../lib/gcc/mingw32/4.6.2/include/c++/bits/stl_function.h:236:22:
er
ror: no match for 'operator<' in '__x < __y'
c:\mingw\bin../lib/gcc/mingw32/4.6.2/include/c++/bits/stl_function.h:236:22:
no
te: candidates are:
c:\mingw\bin../lib/gcc/mingw32/4.6.2/include/c++/bits/stl_pair.h:207:5:
note: t
emplate bool std::operator<(const std::pair<_T1, _T2>&, co
nst std::pair<_T1, _T2>&)
c:\mingw\bin../lib/gcc/mingw32/4.6.2/include/c++/bits/stl_iterator.h:291:5:
not
e: template bool std::operator<(const std::reverse_iterator<_It
erator>&, const std::reverse_iterator<_Iterator>&)
c:\mingw\bin../lib/gcc/mingw32/4.6.2/include/c++/bits/stl_iterator.h:341:5:
not
e: template bool std::operator<(const std::r
everse_iterator<_IteratorL>&, const std::reverse_iterator<_IteratorR>&)
c:\mingw\bin../lib/gcc/mingw32/4.6.2/include/c++/bits/basic_string.h:2510:5:
no
te: template bool std::operator<(cons
t std::basic_string<_CharT, _Traits, _Alloc>&, const std::basic_string<_CharT, _
Traits, _Alloc>&)
c:\mingw\bin../lib/gcc/mingw32/4.6.2/include/c++/bits/basic_string.h:2522:5:
no
te: template bool std::operator<(cons
t std::basic_string<_CharT, _Traits, _Alloc>&, const _CharT*)
c:\mingw\bin../lib/gcc/mingw32/4.6.2/include/c++/bits/basic_string.h:2534:5:
no
te: template bool std::operator<(cons
t _CharT*, const std::basic_string<_CharT, _Traits, _Alloc>&)
c:\mingw\bin../lib/gcc/mingw32/4.6.2/include/c++/bits/stl_vector.h:1290:5:
note
: template bool std::operator<(const std::vector<_Tp, _
Alloc>&, const std::vector<_Tp, _Alloc>&)
c:\mingw\bin../lib/gcc/mingw32/4.6.2/include/c++/bits/stl_list.h:1593:5:
note:
template bool std::operator<(const std::list<_Tp, _Allo
c>&, const std::list<_Tp, _Alloc>&)
c:\mingw\bin../lib/gcc/mingw32/4.6.2/include/c++/bits/stl_tree.h:856:5:
note: t
emplate
bool std::operator<(const std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _All
oc>&, const std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>&)
c:\mingw\bin../lib/gcc/mingw32/4.6.2/include/c++/bits/stl_set.h:713:5:
note: te
mplate bool std::operator<(const std::
set<_Key, _Compare, _Alloc>&, const std::set<_Key, _Compare, _Alloc>&)
c:\mingw\bin../lib/gcc/mingw32/4.6.2/include/c++/bits/stl_multiset.h:696:5:
not
e: template bool std::operator<(const
std::multiset<_Key, _Compare, _Alloc>&, const std::multiset<_Key, _Compare, _All
oc>&)
insert works fine when I make a set s and s.insert(1)
What needs to be done for this code to compile?
Thanks in advance.

You need to overload the operator< :
something like the following:
bool operator<(const Record& rhs) const
{
return a < rhs.a; //assume that you compare the record based on a
}
The reason is that STL set maintains order on elements. std::set supports specifying a comparison function. The default is less which will use operator < to check equality.
Meanwhile, you have to end you class definition with ; otherwise, compile error.
class Record
{
int a, b, c;
public:
//getters and setters
Record(){a = -1; b = -1; c = -1;};
}; //<---Cannot miss this ;

Related

Static assertion failed error in defining set (STL container) with user defined objects c++17

I defined a set with data type as user defined object here.
#include<bits/stdc++.h>
using namespace std;
class triplets{
public:
int x,y,z;
triplets(){
}
triplets(int x,int y,int z){
this->x=x;
this->y=y;
this->z=z;
}
};
class Cmp{
public:
Cmp(){};
bool operator() (const triplets &a, const triplets &b){
if( a.x == b.x){
return a.y < b.y;
}else{
return a.x < b.x;
}
}
};
int main(){
set<triplets,Cmp>s;
s.insert(triplets(2,4,5));
return 0;
}
The code compiles fine in c++11 and c++14 versions. But it doesn't compile in c++17 and above. It throws following error.
In file included from /usr/include/c++/11/map:60,
from /usr/include/x86_64-linux-gnu/c++/11/bits/stdc++.h:81,
from Arrays/TwoPointer/test.cpp:1:
/usr/include/c++/11/bits/stl_tree.h: In instantiation of ‘static const _Key& std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_S_key(std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Const_Link_type) [with _Key = triplets; _Val = triplets; _KeyOfValue = std::_Identity<triplets>; _Compare = Cmp; _Alloc = std::allocator<triplets>; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Const_Link_type = const std::_Rb_tree_node<triplets>*]’:
/usr/include/c++/11/bits/stl_tree.h:2071:47: required from ‘std::pair<std::_Rb_tree_node_base*, std::_Rb_tree_node_base*> std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_get_insert_unique_pos(const key_type&) [with _Key = triplets; _Val = triplets; _KeyOfValue = std::_Identity<triplets>; _Compare = Cmp; _Alloc = std::allocator<triplets>; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::key_type = triplets]’
/usr/include/c++/11/bits/stl_tree.h:2124:4: required from ‘std::pair<std::_Rb_tree_iterator<_Val>, bool> std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_insert_unique(_Arg&&) [with _Arg = triplets; _Key = triplets; _Val = triplets; _KeyOfValue = std::_Identity<triplets>; _Compare = Cmp; _Alloc = std::allocator<triplets>]’
/usr/include/c++/11/bits/stl_set.h:521:25: required from ‘std::pair<typename std::_Rb_tree<_Key, _Key, std::_Identity<_Tp>, _Compare, typename __gnu_cxx::__alloc_traits<_Alloc>::rebind<_Key>::other>::const_iterator, bool> std::set<_Key, _Compare, _Alloc>::insert(std::set<_Key, _Compare, _Alloc>::value_type&&) [with _Key = triplets; _Compare = Cmp; _Alloc = std::allocator<triplets>; typename std::_Rb_tree<_Key, _Key, std::_Identity<_Tp>, _Compare, typename __gnu_cxx::__alloc_traits<_Alloc>::rebind<_Key>::other>::const_iterator = std::_Rb_tree<triplets, triplets, std::_Identity<triplets>, Cmp, std::allocator<triplets> >::const_iterator; typename __gnu_cxx::__alloc_traits<_Alloc>::rebind<_Key>::other = std::allocator<triplets>; typename __gnu_cxx::__alloc_traits<_Alloc>::rebind<_Key> = __gnu_cxx::__alloc_traits<std::allocator<triplets>, triplets>::rebind<triplets>; typename _Alloc::value_type = triplets; std::set<_Key, _Compare, _Alloc>::value_type = triplets]’
Arrays/TwoPointer/test.cpp:29:13: required from here
/usr/include/c++/11/bits/stl_tree.h:770:15: error: static assertion failed: comparison object must be invocable as const
770 | is_invocable_v<const _Compare&, const _Key&, const _Key&>,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/c++/11/bits/stl_tree.h:770:15: note: ‘std::is_invocable_v<const Cmp&, const triplets&, const triplets&>’ evaluates to false
Any idea how should I define the set?
bool operator() (const triplets &a, const triplets &b){
should be
bool operator() (const triplets &a, const triplets &b) const{

required from 'std::pair<std::_Rb_tree_iterator<_Val>, bool> std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_insert_unique

I'm getting a compilation error,
required from 'std::pair<std::_Rb_tree_iterator<_Val>, bool> std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_insert_unique(_Arg&&) [with _Arg = Solution::EnhancedNode* const&; _Key = Solution::EnhancedNode*; _Val = Solution::EnhancedNode*; _KeyOfValue = std::_Identity<Solution::EnhancedNode*>; _Compare = Solution::EnhancedNodeComparator; _Alloc = std::allocator<Solution::EnhancedNode*>]'
Unfortunately there is no line number, but my removing sections of code, I believe it has something to do with an std::set that I want to apply a custom comparator to:
class EnhancedNode {
public:
EnhancedNode(TreeNode* node) {
node_ = node;
distance_ = numeric_limits<double>::max();
discarded_ = false;
}
TreeNode* node_;
double distance_;
bool discarded_;
};
struct EnhancedNodeComparator {
bool operator() (const EnhancedNode*& a, const EnhancedNode*& b) const {
return a->distance_ < b->distance_;
}
};
set<EnhancedNode*, EnhancedNodeComparator> closest_;
set<EnhancedNode*, EnhancedNodeComparator> next_;
Am I doing anything obviously wrong?
The comparator of std::set should definitely accept references to the const qualified type which is in the set.
What you got wrong is the qualification of the type in the set. It's EnhancedNode*, so qualifying it with const should give EnhancedNode* const. And not const EnhancedNode*.
This is once again a case of leading const being misleading. Change your original comparator, with reference and all, to this:
struct EnhancedNodeComparator {
bool operator() (EnhancedNode const * const& a, EnhancedNode const * const& b) const {
return a->distance_ < b->distance_;
}
};
You can keep the const-qualified pointee, as well. Since C++ explicitly allows it.
The reason that your issue was fixed when you got rid of the reference, is that top-level const is ignored when passing by value. So it didn't matter the the pointer your function received as an argument wasn't const qualified. It was just a copy of the original.
While creating a Minimal, Complete, VerifiableTM example, I was able to solve my problem. I'm posting it anyway because Google surprisingly had zero hits for the first portions of my error in quotes.
Turns out I didn't need the &s in
struct EnhancedNodeComparator {
bool operator() (const EnhancedNode*& a, const EnhancedNode*& b) const {
I found this out by compiling on a different compiler, http://cpp.sh,
#include <limits>
#include <set>
using namespace std;
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};
class EnhancedNode {
public:
EnhancedNode(TreeNode* node) {
node_ = node;
distance_ = numeric_limits<double>::max();
discarded_ = false;
}
TreeNode* node_;
double distance_;
bool discarded_;
};
struct EnhancedNodeComparator {
bool operator() (const EnhancedNode*& a, const EnhancedNode*& b) const {
return a->distance_ < b->distance_;
}
};
int main()
{
set<EnhancedNode*, EnhancedNodeComparator> closest_;
closest_.insert(new EnhancedNode(new TreeNode(1)));
return 0;
}
and getting a more helpful error:
In file included from /usr/include/c++/4.9/set:60:0,
from 3:
/usr/include/c++/4.9/bits/stl_tree.h: In instantiation of 'std::pair<std::_Rb_tree_node_base*, std::_Rb_tree_node_base*> std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_get_insert_unique_pos(const key_type&) [with _Key = EnhancedNode*; _Val = EnhancedNode*; _KeyOfValue = std::_Identity<EnhancedNode*>; _Compare = EnhancedNodeComparator; _Alloc = std::allocator<EnhancedNode*>; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::key_type = EnhancedNode*]':
/usr/include/c++/4.9/bits/stl_tree.h:1498:47: required from 'std::pair<std::_Rb_tree_iterator<_Val>, bool> std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_insert_unique(_Arg&&) [with _Arg = EnhancedNode*; _Key = EnhancedNode*; _Val = EnhancedNode*; _KeyOfValue = std::_Identity<EnhancedNode*>; _Compare = EnhancedNodeComparator; _Alloc = std::allocator<EnhancedNode*>]'
/usr/include/c++/4.9/bits/stl_set.h:511:40: required from 'std::pair<typename std::_Rb_tree<_Key, _Key, std::_Identity<_Key>, _Compare, typename __gnu_cxx::__alloc_traits<_Alloc>::rebind<_Key>::other>::const_iterator, bool> std::set<_Key, _Compare, _Alloc>::insert(std::set<_Key, _Compare, _Alloc>::value_type&&) [with _Key = EnhancedNode*; _Compare = EnhancedNodeComparator; _Alloc = std::allocator<EnhancedNode*>; typename std::_Rb_tree<_Key, _Key, std::_Identity<_Key>, _Compare, typename __gnu_cxx::__alloc_traits<_Alloc>::rebind<_Key>::other>::const_iterator = std::_Rb_tree_const_iterator<EnhancedNode*>; std::set<_Key, _Compare, _Alloc>::value_type = EnhancedNode*]'
33:54: required from here
/usr/include/c++/4.9/bits/stl_tree.h:1445:11: error: no match for call to '(EnhancedNodeComparator) (EnhancedNode* const&, EnhancedNode* const&)'
__comp = _M_impl._M_key_compare(__k, _S_key(__x));
^
24:8: note: candidate is:
25:10: note: bool EnhancedNodeComparator::operator()(const EnhancedNode*&, const EnhancedNode*&) const
25:10: note: no known conversion for argument 1 from 'const key_type {aka EnhancedNode* const}' to 'const EnhancedNode*&'
In file included from /usr/include/c++/4.9/set:60:0,
from 3:
/usr/include/c++/4.9/bits/stl_tree.h:1456:7: error: no match for call to '(EnhancedNodeComparator) (EnhancedNode* const&, EnhancedNode* const&)'
if (_M_impl._M_key_compare(_S_key(__j._M_node), __k))
^
24:8: note: candidate is:
25:10: note: bool EnhancedNodeComparator::operator()(const EnhancedNode*&, const EnhancedNode*&) const
25:10: note: no known conversion for argument 1 from 'EnhancedNode* const' to 'const EnhancedNode*&'
In file included from /usr/include/c++/4.9/set:60:0,
from 3:
/usr/include/c++/4.9/bits/stl_tree.h: In instantiation of 'std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_insert_(std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Base_ptr, std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Base_ptr, _Arg&&) [with _Arg = EnhancedNode*; _Key = EnhancedNode*; _Val = EnhancedNode*; _KeyOfValue = std::_Identity<EnhancedNode*>; _Compare = EnhancedNodeComparator; _Alloc = std::allocator<EnhancedNode*>; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator = std::_Rb_tree_iterator<EnhancedNode*>; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Base_ptr = std::_Rb_tree_node_base*]':
/usr/include/c++/4.9/bits/stl_tree.h:1502:38: required from 'std::pair<std::_Rb_tree_iterator<_Val>, bool> std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_insert_unique(_Arg&&) [with _Arg = EnhancedNode*; _Key = EnhancedNode*; _Val = EnhancedNode*; _KeyOfValue = std::_Identity<EnhancedNode*>; _Compare = EnhancedNodeComparator; _Alloc = std::allocator<EnhancedNode*>]'
/usr/include/c++/4.9/bits/stl_set.h:511:40: required from 'std::pair<typename std::_Rb_tree<_Key, _Key, std::_Identity<_Key>, _Compare, typename __gnu_cxx::__alloc_traits<_Alloc>::rebind<_Key>::other>::const_iterator, bool> std::set<_Key, _Compare, _Alloc>::insert(std::set<_Key, _Compare, _Alloc>::value_type&&) [with _Key = EnhancedNode*; _Compare = EnhancedNodeComparator; _Alloc = std::allocator<EnhancedNode*>; typename std::_Rb_tree<_Key, _Key, std::_Identity<_Key>, _Compare, typename __gnu_cxx::__alloc_traits<_Alloc>::rebind<_Key>::other>::const_iterator = std::_Rb_tree_const_iterator<EnhancedNode*>; std::set<_Key, _Compare, _Alloc>::value_type = EnhancedNode*]'
33:54: required from here
/usr/include/c++/4.9/bits/stl_tree.h:1140:8: error: no match for call to '(EnhancedNodeComparator) (EnhancedNode*&, EnhancedNode* const&)'
|| _M_impl._M_key_compare(_KeyOfValue()(__v),
^
24:8: note: candidate is:
25:10: note: bool EnhancedNodeComparator::operator()(const EnhancedNode*&, const EnhancedNode*&) const
25:10: note: no known conversion for argument 1 from 'EnhancedNode*' to 'const EnhancedNode*&'
I don't really understand why this is so. All the examples for custom comparators for std::set I found online seemed to add &. If someone could explain as an answer, I would select it as the complete answer.

C++ (NetBeans) stating I'm using an operator that appears nowhere in my code?

I'm perplexed by an error I'm getting with c++ using NetBeans. I'm not the best at pointers vs. non-pointers (native Java coder), so keep that in mind.
I'm working on a watered-down version of the "Netflix Challenge" for data structures in uni, and I'm on the final method of displaying the top n movies for each user. Below the code is the (copious) error message(s) I'm getting. It seems to say I'm using a less-than operator on a MovieBase::Movie, but I'm only using it on floats - and it states it's being called from the wrong line (I've marked it in comments).
In addition, the final cout << at the end is stating something about discarding qualifiers, and after searching around I still had no idea what it was trying to tell me.
Can anyone offer a little insight? Thank you!
map<MovieBase::Movie,float> UserBase::topMovieList(int moviesToShow, MovieBase* mb, unsigned int userID){
map<MovieBase::Movie,float> topList;
vector<MovieBase::Movie>::iterator mit = mb->allMovies.begin();
while(mit!=mb->allMovies.end()){
MovieBase::Movie thisMovie = *mit;
vector<string> theseGenres = thisMovie.getGenres();
float weightedScore = 0;
for(int i=0;i<theseGenres.size();i++){
weightedScore+=this->get(userID)->preferenceFactors.at(theseGenres[i])*(thisMovie.getAverage());
}
weightedScore = weightedScore/theseGenres.size();
if(topList.empty()){
map<MovieBase::Movie,float>::iterator bit = topList.begin();
//The error occurs on the line below
topList.insert(bit,std::make_pair(thisMovie,weightedScore));
}
else{
map<MovieBase::Movie,float>::iterator bit = topList.begin();
map<MovieBase::Movie,float>::iterator lit = topList.end();
lit--;
if(bit->second==lit->second||(weightedScore>bit->second)){
while(bit->second<weightedScore){
bit++;
}
topList.insert(bit,std::make_pair(thisMovie,weightedScore));
if(topList.size()>moviesToShow){
bit = topList.begin();
topList.erase(bit);
}
}
}
mit++;
}
map<MovieBase::Movie,float>::iterator finalPrintIterator = topList.begin();
cout << "User " << userID << "'s Top " << moviesToShow << " movies:" << endl;
while(finalPrintIterator!=topList.end()){
cout << finalPrintIterator->first.getName() << "(" << finalPrintIterator->first.getYear() << ") - Weighted Score: " << finalPrintIterator->second << endl;
finalPrintIterator++;
}
return topList;
}
"/usr/bin/make" -f nbproject/Makefile-Debug.mk QMAKE= SUBPROJECTS= .build-conf
make[1]: Entering directory '/cygdrive/s/Production/Projects/CSE250/250-REGAN-PROJ2/NetflixChallenge'
"/usr/bin/make" -f nbproject/Makefile-Debug.mk dist/Debug/Cygwin_4.x-Windows/netflixchallenge.exe
make[2]: Entering directory '/cygdrive/s/Production/Projects/CSE250/250-REGAN-PROJ2/NetflixChallenge'
mkdir -p build/Debug/Cygwin_4.x-Windows
rm -f "build/Debug/Cygwin_4.x-Windows/UserBase.o.d"
g++ -c -g -MMD -MP -MF "build/Debug/Cygwin_4.x-Windows/UserBase.o.d" -o build/Debug/Cygwin_4.x-Windows/UserBase.o UserBase.cpp
UserBase.cpp: In member function ‘std::map<MovieBase::Movie, float> UserBase::topMovieList(int, MovieBase*, unsigned int)’:
UserBase.cpp:146:51: error: passing ‘const MovieBase::Movie’ as ‘this’ argument of ‘std::string MovieBase::Movie::getName()’ discards qualifiers [-fpermissive]
cout << finalPrintIterator->first.getName() << "(" << finalPrintIterator->first.getYear() << ") - Weighted Score: " << finalPrintIterator->second << endl;
^
UserBase.cpp:146:97: error: passing ‘const MovieBase::Movie’ as ‘this’ argument of ‘unsigned int MovieBase::Movie::getYear()’ discards qualifiers [-fpermissive]
cout << finalPrintIterator->first.getName() << "(" << finalPrintIterator->first.getYear() << ") - Weighted Score: " << finalPrintIterator->second << endl;
^
/usr/lib/gcc/x86_64-pc-cygwin/4.8.2/include/c++/bits/stl_function.h: In instantiation of ‘bool std::less<_Tp>::operator()(const _Tp&, const _Tp&) const [with _Tp = MovieBase::Movie]’:
/usr/lib/gcc/x86_64-pc-cygwin/4.8.2/include/c++/bits/stl_tree.h:1422:8: required from ‘std::pair<std::_Rb_tree_node_base*, std::_Rb_tree_node_base*> std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_get_insert_hint_unique_pos(std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::const_iterator, const key_type&) [with _Key = MovieBase::Movie; _Val = std::pair<const MovieBase::Movie, float>; _KeyOfValue = std::_Select1st<std::pair<const MovieBase::Movie, float> >; _Compare = std::less<MovieBase::Movie>; _Alloc = std::allocator<std::pair<const MovieBase::Movie, float> >; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::const_iterator = std::_Rb_tree_const_iterator<std::pair<const MovieBase::Movie, float> >; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::key_type = MovieBase::Movie]’
/usr/lib/gcc/x86_64-pc-cygwin/4.8.2/include/c++/bits/stl_tree.h:1478:64: required from ‘std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_insert_unique_(std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::const_iterator, const _Val&) [with _Key = MovieBase::Movie; _Val = std::pair<const MovieBase::Movie, float>; _KeyOfValue = std::_Select1st<std::pair<const MovieBase::Movie, float> >; _Compare = std::less<MovieBase::Movie>; _Alloc = std::allocator<std::pair<const MovieBase::Movie, float> >; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator = std::_Rb_tree_iterator<std::pair<const MovieBase::Movie, float> >; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::const_iterator = std::_Rb_tree_const_iterator<std::pair<const MovieBase::Movie, float> >]’
/usr/lib/gcc/x86_64-pc-cygwin/4.8.2/include/c++/bits/stl_map.h:648:54: required from ‘std::map<_Key, _Tp, _Compare, _Alloc>::iterator std::map<_Key, _Tp, _Compare, _Alloc>::insert(std::map<_Key, _Tp, _Compare, _Alloc>::iterator, const value_type&) [with _Key = MovieBase::Movie; _Tp = float; _Compare = std::less<MovieBase::Movie>; _Alloc = std::allocator<std::pair<const MovieBase::Movie, float> >; std::map<_Key, _Tp, _Compare, _Alloc>::iterator = std::_Rb_tree_iterator<std::pair<const MovieBase::Movie, float> >; std::map<_Key, _Tp, _Compare, _Alloc>::value_type = std::pair<const MovieBase::Movie, float>]’
UserBase.cpp:124:71: required from here
/usr/lib/gcc/x86_64-pc-cygwin/4.8.2/include/c++/bits/stl_function.h:235:20: error: no match for ‘operator<’ (operand types are ‘const MovieBase::Movie’ and ‘const MovieBase::Movie’)
{ return __x < __y; }
^
/usr/lib/gcc/x86_64-pc-cygwin/4.8.2/include/c++/bits/stl_function.h:235:20: note: candidates are:
In file included from /usr/lib/gcc/x86_64-pc-cygwin/4.8.2/include/c++/bits/stl_algobase.h:64:0,
from /usr/lib/gcc/x86_64-pc-cygwin/4.8.2/include/c++/bits/char_traits.h:39,
from /usr/lib/gcc/x86_64-pc-cygwin/4.8.2/include/c++/string:40,
from UserBase.h:10,
from UserBase.cpp:9:
/usr/lib/gcc/x86_64-pc-cygwin/4.8.2/include/c++/bits/stl_pair.h:220:5: note: template<class _T1, class _T2> bool std::operator<(const std::pair<_T1, _T2>&, const std::pair<_T1, _T2>&)
operator<(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
^
/usr/lib/gcc/x86_64-pc-cygwin/4.8.2/include/c++/bits/stl_pair.h:220:5: note: template argument deduction/substitution failed:
In file included from /usr/lib/gcc/x86_64-pc-cygwin/4.8.2/include/c++/string:48:0,
from UserBase.h:10,
from UserBase.cpp:9:
/usr/lib/gcc/x86_64-pc-cygwin/4.8.2/include/c++/bits/stl_function.h:235:20: note: ‘const MovieBase::Movie’ is not derived from ‘const std::pair<_T1, _T2>’
{ return __x < __y; }
^
In file included from /usr/lib/gcc/x86_64-pc-cygwin/4.8.2/include/c++/bits/stl_algobase.h:67:0,
from /usr/lib/gcc/x86_64-pc-cygwin/4.8.2/include/c++/bits/char_traits.h:39,
from /usr/lib/gcc/x86_64-pc-cygwin/4.8.2/include/c++/string:40,
from UserBase.h:10,
from UserBase.cpp:9:
/usr/lib/gcc/x86_64-pc-cygwin/4.8.2/include/c++/bits/stl_iterator.h:297:5: note: template<class _Iterator> bool std::operator<(const std::reverse_iterator<_Iterator>&, const std::reverse_iterator<_Iterator>&)
operator<(const reverse_iterator<_Iterator>& __x,
^
/usr/lib/gcc/x86_64-pc-cygwin/4.8.2/include/c++/bits/stl_iterator.h:297:5: note: template argument deduction/substitution failed:
In file included from /usr/lib/gcc/x86_64-pc-cygwin/4.8.2/include/c++/string:48:0,
from UserBase.h:10,
from UserBase.cpp:9:
/usr/lib/gcc/x86_64-pc-cygwin/4.8.2/include/c++/bits/stl_function.h:235:20: note: ‘const MovieBase::Movie’ is not derived from ‘const std::reverse_iterator<_Iterator>’
{ return __x < __y; }
^
In file included from /usr/lib/gcc/x86_64-pc-cygwin/4.8.2/include/c++/bits/stl_algobase.h:67:0,
from /usr/lib/gcc/x86_64-pc-cygwin/4.8.2/include/c++/bits/char_traits.h:39,
from /usr/lib/gcc/x86_64-pc-cygwin/4.8.2/include/c++/string:40,
from UserBase.h:10,
from UserBase.cpp:9:
/usr/lib/gcc/x86_64-pc-cygwin/4.8.2/include/c++/bits/stl_iterator.h:347:5: note: template<class _IteratorL, class _IteratorR> bool std::operator<(const std::reverse_iterator<_Iterator>&, const std::reverse_iterator<_IteratorR>&)
operator<(const reverse_iterator<_IteratorL>& __x,
^
/usr/lib/gcc/x86_64-pc-cygwin/4.8.2/include/c++/bits/stl_iterator.h:347:5: note: template argument deduction/substitution failed:
In file included from /usr/lib/gcc/x86_64-pc-cygwin/4.8.2/include/c++/string:48:0,
from UserBase.h:10,
from UserBase.cpp:9:
/usr/lib/gcc/x86_64-pc-cygwin/4.8.2/include/c++/bits/stl_function.h:235:20: note: ‘const MovieBase::Movie’ is not derived from ‘const std::reverse_iterator<_Iterator>’
{ return __x < __y; }
^
In file included from /usr/lib/gcc/x86_64-pc-cygwin/4.8.2/include/c++/string:52:0,
from UserBase.h:10,
from UserBase.cpp:9:
/usr/lib/gcc/x86_64-pc-cygwin/4.8.2/include/c++/bits/basic_string.h:2569:5: note: template<class _CharT, class _Traits, class _Alloc> bool std::operator<(const std::basic_string<_CharT, _Traits, _Alloc>&, const std::basic_string<_CharT, _Traits, _Alloc>&)
operator<(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
^
/usr/lib/gcc/x86_64-pc-cygwin/4.8.2/include/c++/bits/basic_string.h:2569:5: note: template argument deduction/substitution failed:
In file included from /usr/lib/gcc/x86_64-pc-cygwin/4.8.2/include/c++/string:48:0,
from UserBase.h:10,
from UserBase.cpp:9:
/usr/lib/gcc/x86_64-pc-cygwin/4.8.2/include/c++/bits/stl_function.h:235:20: note: ‘const MovieBase::Movie’ is not derived from ‘const std::basic_string<_CharT, _Traits, _Alloc>’
{ return __x < __y; }
^
In file included from /usr/lib/gcc/x86_64-pc-cygwin/4.8.2/include/c++/string:52:0,
from UserBase.h:10,
from UserBase.cpp:9:
/usr/lib/gcc/x86_64-pc-cygwin/4.8.2/include/c++/bits/basic_string.h:2581:5: note: template<class _CharT, class _Traits, class _Alloc> bool std::operator<(const std::basic_string<_CharT, _Traits, _Alloc>&, const _CharT*)
operator<(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
^
/usr/lib/gcc/x86_64-pc-cygwin/4.8.2/include/c++/bits/basic_string.h:2581:5: note: template argument deduction/substitution failed:
In file included from /usr/lib/gcc/x86_64-pc-cygwin/4.8.2/include/c++/string:48:0,
from UserBase.h:10,
from UserBase.cpp:9:
/usr/lib/gcc/x86_64-pc-cygwin/4.8.2/include/c++/bits/stl_function.h:235:20: note: ‘const MovieBase::Movie’ is not derived from ‘const std::basic_string<_CharT, _Traits, _Alloc>’
{ return __x < __y; }
^
In file included from /usr/lib/gcc/x86_64-pc-cygwin/4.8.2/include/c++/string:52:0,
from UserBase.h:10,
from UserBase.cpp:9:
/usr/lib/gcc/x86_64-pc-cygwin/4.8.2/include/c++/bits/basic_string.h:2593:5: note: template<class _CharT, class _Traits, class _Alloc> bool std::operator<(const _CharT*, const std::basic_string<_CharT, _Traits, _Alloc>&)
operator<(const _CharT* __lhs,
^
/usr/lib/gcc/x86_64-pc-cygwin/4.8.2/include/c++/bits/basic_string.h:2593:5: note: template argument deduction/substitution failed:
In file included from /usr/lib/gcc/x86_64-pc-cygwin/4.8.2/include/c++/string:48:0,
from UserBase.h:10,
from UserBase.cpp:9:
/usr/lib/gcc/x86_64-pc-cygwin/4.8.2/include/c++/bits/stl_function.h:235:20: note: mismatched types ‘const _CharT*’ and ‘MovieBase::Movie’
{ return __x < __y; }
^
In file included from /usr/lib/gcc/x86_64-pc-cygwin/4.8.2/include/c++/map:60:0,
from UserBase.h:11,
from UserBase.cpp:9:
/usr/lib/gcc/x86_64-pc-cygwin/4.8.2/include/c++/bits/stl_tree.h:917:5: note: template<class _Key, class _Val, class _KeyOfValue, class _Compare, class _Alloc> bool std::operator<(const std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>&, const std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>&)
operator<(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x,
^
/usr/lib/gcc/x86_64-pc-cygwin/4.8.2/include/c++/bits/stl_tree.h:917:5: note: template argument deduction/substitution failed:
In file included from /usr/lib/gcc/x86_64-pc-cygwin/4.8.2/include/c++/string:48:0,
from UserBase.h:10,
from UserBase.cpp:9:
/usr/lib/gcc/x86_64-pc-cygwin/4.8.2/include/c++/bits/stl_function.h:235:20: note: ‘const MovieBase::Movie’ is not derived from ‘const std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>’
{ return __x < __y; }
^
In file included from /usr/lib/gcc/x86_64-pc-cygwin/4.8.2/include/c++/map:61:0,
from UserBase.h:11,
from UserBase.cpp:9:
/usr/lib/gcc/x86_64-pc-cygwin/4.8.2/include/c++/bits/stl_map.h:979:5: note: template<class _Key, class _Tp, class _Compare, class _Alloc> bool std::operator<(const std::map<_Key, _Tp, _Compare, _Alloc>&, const std::map<_Key, _Tp, _Compare, _Alloc>&)
operator<(const map<_Key, _Tp, _Compare, _Alloc>& __x,
^
/usr/lib/gcc/x86_64-pc-cygwin/4.8.2/include/c++/bits/stl_map.h:979:5: note: template argument deduction/substitution failed:
In file included from /usr/lib/gcc/x86_64-pc-cygwin/4.8.2/include/c++/string:48:0,
from UserBase.h:10,
from UserBase.cpp:9:
/usr/lib/gcc/x86_64-pc-cygwin/4.8.2/include/c++/bits/stl_function.h:235:20: note: ‘const MovieBase::Movie’ is not derived from ‘const std::map<_Key, _Tp, _Compare, _Alloc>’
{ return __x < __y; }
^
In file included from /usr/lib/gcc/x86_64-pc-cygwin/4.8.2/include/c++/map:62:0,
from UserBase.h:11,
from UserBase.cpp:9:
/usr/lib/gcc/x86_64-pc-cygwin/4.8.2/include/c++/bits/stl_multimap.h:881:5: note: template<class _Key, class _Tp, class _Compare, class _Alloc> bool std::operator<(const std::multimap<_Key, _Tp, _Compare, _Alloc>&, const std::multimap<_Key, _Tp, _Compare, _Alloc>&)
operator<(const multimap<_Key, _Tp, _Compare, _Alloc>& __x,
^
/usr/lib/gcc/x86_64-pc-cygwin/4.8.2/include/c++/bits/stl_multimap.h:881:5: note: template argument deduction/substitution failed:
In file included from /usr/lib/gcc/x86_64-pc-cygwin/4.8.2/include/c++/string:48:0,
from UserBase.h:10,
from UserBase.cpp:9:
/usr/lib/gcc/x86_64-pc-cygwin/4.8.2/include/c++/bits/stl_function.h:235:20: note: ‘const MovieBase::Movie’ is not derived from ‘const std::multimap<_Key, _Tp, _Compare, _Alloc>’
{ return __x < __y; }
^
In file included from /usr/lib/gcc/x86_64-pc-cygwin/4.8.2/include/c++/vector:64:0,
from MovieBase.h:11,
from UserBase.h:12,
from UserBase.cpp:9:
/usr/lib/gcc/x86_64-pc-cygwin/4.8.2/include/c++/bits/stl_vector.h:1420:5: note: template<class _Tp, class _Alloc> bool std::operator<(const std::vector<_Tp, _Alloc>&, const std::vector<_Tp, _Alloc>&)
operator<(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y)
^
/usr/lib/gcc/x86_64-pc-cygwin/4.8.2/include/c++/bits/stl_vector.h:1420:5: note: template argument deduction/substitution failed:
In file included from /usr/lib/gcc/x86_64-pc-cygwin/4.8.2/include/c++/string:48:0,
from UserBase.h:10,
from UserBase.cpp:9:
/usr/lib/gcc/x86_64-pc-cygwin/4.8.2/include/c++/bits/stl_function.h:235:20: note: ‘const MovieBase::Movie’ is not derived from ‘const std::vector<_Tp, _Alloc>’
{ return __x < __y; }
^
nbproject/Makefile-Debug.mk:73: recipe for target 'build/Debug/Cygwin_4.x-Windows/UserBase.o' failed
make[2]: *** [build/Debug/Cygwin_4.x-Windows/UserBase.o] Error 1
make[2]: Leaving directory '/cygdrive/s/Production/Projects/CSE250/250-REGAN-PROJ2/NetflixChallenge'
nbproject/Makefile-Debug.mk:61: recipe for target '.build-conf' failed
make[1]: *** [.build-conf] Error 2
make[1]: Leaving directory '/cygdrive/s/Production/Projects/CSE250/250-REGAN-PROJ2/NetflixChallenge'
nbproject/Makefile-impl.mk:39: recipe for target '.build-impl' failed
make: *** [.build-impl] Error 2
BUILD FAILED (exit value 2, total time: 1s)
Not sure what the line 146 in userbase.cpp is, but you seem to call non-const member function on const object there.
The problem is that std::map<T> requires that the type T be equipped with an operator<() (either a 1-arg method or a 2-arg free function), but your MovieBase::Movie class doesn't provide one. std::map<T> needs this operator because it internally stores key-value pairs in a balanced binary tree, and this requires comparing different key values.
My guess is that
vector<MovieBase::Movie>::iterator
is the problem. The < it contains will probably be interpreted as a less-than sign if, for example, you haven't declared std::vector<T> by writing #include <vector> near the top of your code.

using the find function from algorithm on vector

I want to use the find function from the algorithm library on a vector object. The vector object is a vector of customers, (Customer is a class I made). I first ran it and it gave me an error in stl_algo.h. I search the web for it and I searched here for it too, I found a question here about it and I ran the same code, but I still got that error.
My code is here:
Header File:
#include <string>
#include <sstream>
#include <map>
#include <vector>
using namespace std;
enum Status {ACTIVE, INACTIVE};
class Customer {
private:
// ID Database class for storing customers' ids
class IdDB {
private:
friend class Customer;
// member field
static map <string, int> idList;
// member function
static int getNumber (const string &threeLetters) {
map<string, int>::iterator i = idList.find(threeLetters);
if (i == idList.end()) {
idList.insert(pair <string, int> (threeLetters, 0));
return 0;
}else{
return ++(i->second);
}
}
};
string id;
string name;
string address;
Status status;
void makeId () {
string threeLetters = name.substr(0, 3);
int idNum = IdDB::getNumber(threeLetters);
stringstream oss;
oss << threeLetters << idNum;
id = oss.str();
}
public:
Customer (const string&, const string&, const Status);
// Accessor Methods
string &getId ();
string &getName ();
string &getAddress ();
Status getStatus ();
// Mutator Methods
void setAddress (const string&);
void setStatus (const Status);
// Misc. Methods
void printStatus ();
// Equality Operator Overloading
friend bool operator == (Customer&, Customer&);
};
class CustomerDB {
private:
static vector<Customer> customersList;
public:
static void addCustomer (const Customer&);
static void deleteCustomer (Customer&);
};
Source Code:
#include <iostream>
#include <string>
#include <algorithm>
#include "Customer.h"
using namespace std;
map<string, int> Customer::IdDB::idList;
Customer::Customer (const string &cName, const string &cAddress, const Status cStatus) : name(cName), address(cAddress), status(cStatus) {
makeId();
}
// Accessor Methods
string &Customer::getId () { return id; }
string &Customer::getName () { return name; }
string &Customer::getAddress () { return address; }
Status Customer::getStatus () { return status; }
// Mutator Methods
void Customer::setAddress (const string &newAddress) { address = newAddress; }
void Customer::setStatus (const Status newStatus) { status = newStatus; }
// Misc. Methods
void Customer::printStatus () {
if (status == ACTIVE)
cout << "Active";
else
cout << "In-Active";
}
vector<Customer> CustomerDB::customersList;
void CustomerDB::addCustomer (const Customer &customer) {
customersList.push_back(customer);
}
void CustomerDB::deleteCustomer (Customer &customer) {
vector<Customer>::iterator i;
i = find(customersList.begin(), customersList.end(), customer); // getting error in here
}
// Equality Operator Overloading
bool operator == (Customer &cust1, Customer &cust2) {
return cust1.getId() == cust2.getId();
}
after building with Code::Blocks, I got this,
in header file stl_algo.h:
}
/// This is an overload used by find() for the RAI case.
template<typename _RandomAccessIterator, typename _Tp>
_RandomAccessIterator
__find(_RandomAccessIterator __first, _RandomAccessIterator __last,
const _Tp& __val, random_access_iterator_tag)
{
typename iterator_traits<_RandomAccessIterator>::difference_type
__trip_count = (__last - __first) >> 2;
for (; __trip_count > 0; --__trip_count)
{
if (*__first == __val) // error in here exactly getting a red block
return __first;
++__first;
if (*__first == __val)
return __first;
++__first;
if (*__first == __val)
return __first;
Thanks
EDIT: Here is the build log
Compiling: C:\Users\KiKo-SaMa\Desktop\C++\DVD_App\Customer.cpp
In file included from c:\mingw\bin\../lib/gcc/mingw32/4.6.2/include/c++/algorithm:63:0,
from C:\Users\KiKo-SaMa\Desktop\C++\DVD_App\Customer.cpp:5:
c:\mingw\bin\../lib/gcc/mingw32/4.6.2/include/c++/bits/stl_algo.h: In function '_RandomAccessIterator std::__find(_RandomAccessIterator, _RandomAccessIterator, const _Tp&, std::random_access_iterator_tag) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<Customer*, std::vector<Customer> >, _Tp = Customer]':
c:\mingw\bin\../lib/gcc/mingw32/4.6.2/include/c++/bits/stl_algo.h:4403:45: instantiated from '_IIter std::find(_IIter, _IIter, const _Tp&) [with _IIter = __gnu_cxx::__normal_iterator<Customer*, std::vector<Customer> >, _Tp = Customer]'
C:\Users\KiKo-SaMa\Desktop\C++\DVD_App\Customer.cpp:42:66: instantiated from here
c:\mingw\bin\../lib/gcc/mingw32/4.6.2/include/c++/bits/stl_algo.h:162:4: error: no match for 'operator==' in '__first.__gnu_cxx::__normal_iterator<_Iterator, _Container>::operator* [with _Iterator = Customer*, _Container = std::vector<Customer>, __gnu_cxx::__normal_iterator<_Iterator, _Container>::reference = Customer&]() == __val'
c:\mingw\bin\../lib/gcc/mingw32/4.6.2/include/c++/bits/stl_algo.h:162:4: note: candidates are:
c:\mingw\bin\../lib/gcc/mingw32/4.6.2/include/c++/bits/postypes.h:218:5: note: template<class _StateT> bool std::operator==(const std::fpos<_StateT>&, const std::fpos<_StateT>&)
c:\mingw\bin\../lib/gcc/mingw32/4.6.2/include/c++/bits/stl_pair.h:201:5: note: template<class _T1, class _T2> bool std::operator==(const std::pair<_T1, _T2>&, const std::pair<_T1, _T2>&)
c:\mingw\bin\../lib/gcc/mingw32/4.6.2/include/c++/bits/stl_iterator.h:285:5: note: template<class _Iterator> bool std::operator==(const std::reverse_iterator<_Iterator>&, const std::reverse_iterator<_Iterator>&)
c:\mingw\bin\../lib/gcc/mingw32/4.6.2/include/c++/bits/stl_iterator.h:335:5: note: template<class _IteratorL, class _IteratorR> bool std::operator==(const std::reverse_iterator<_IteratorL>&, const std::reverse_iterator<_IteratorR>&)
c:\mingw\bin\../lib/gcc/mingw32/4.6.2/include/c++/bits/allocator.h:122:5: note: template<class _T1, class _T2> bool std::operator==(const std::allocator<_T1>&, const std::allocator<_T2>&)
c:\mingw\bin\../lib/gcc/mingw32/4.6.2/include/c++/bits/allocator.h:127:5: note: template<class _Tp> bool std::operator==(const std::allocator<_Tp1>&, const std::allocator<_Tp1>&)
c:\mingw\bin\../lib/gcc/mingw32/4.6.2/include/c++/bits/basic_string.h:2427:5: note: template<class _CharT, class _Traits, class _Alloc> bool std::operator==(const std::basic_string<_CharT, _Traits, _Alloc>&, const std::basic_string<_CharT, _Traits, _Alloc>&)
c:\mingw\bin\../lib/gcc/mingw32/4.6.2/include/c++/bits/basic_string.h:2434:5: note: template<class _CharT> typename __gnu_cxx::__enable_if<std::__is_char<_Tp>::__value, bool>::__type std::operator==(const std::basic_string<_CharT>&, const std::basic_string<_CharT>&)
c:\mingw\bin\../lib/gcc/mingw32/4.6.2/include/c++/bits/basic_string.h:2448:5: note: template<class _CharT, class _Traits, class _Alloc> bool std::operator==(const _CharT*, const std::basic_string<_CharT, _Traits, _Alloc>&)
c:\mingw\bin\../lib/gcc/mingw32/4.6.2/include/c++/bits/basic_string.h:2460:5: note: template<class _CharT, class _Traits, class _Alloc> bool std::operator==(const std::basic_string<_CharT, _Traits, _Alloc>&, const _CharT*)
c:\mingw\bin\../lib/gcc/mingw32/4.6.2/include/c++/bits/streambuf_iterator.h:194:5: note: template<class _CharT, class _Traits> bool std::operator==(const std::istreambuf_iterator<_CharT, _Traits>&, const std::istreambuf_iterator<_CharT, _Traits>&)
c:\mingw\bin\../lib/gcc/mingw32/4.6.2/include/c++/bits/stl_tree.h:309:5: note: template<class _Val> bool std::operator==(const std::_Rb_tree_iterator<_Tp>&, const std::_Rb_tree_const_iterator<_Val>&)
c:\mingw\bin\../lib/gcc/mingw32/4.6.2/include/c++/bits/stl_tree.h:846:5: note: template<class _Key, class _Val, class _KeyOfValue, class _Compare, class _Alloc> bool std::operator==(const std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>&, const std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>&)
c:\mingw\bin\../lib/gcc/mingw32/4.6.2/include/c++/bits/stl_map.h:877:5: note: template<class _Key, class _Tp, class _Compare, class _Alloc> bool std::operator==(const std::map<_Key, _Tp, _Compare, _Alloc>&, const std::map<_Key, _Tp, _Compare, _Alloc>&)
c:\mingw\bin\../lib/gcc/mingw32/4.6.2/include/c++/bits/stl_multimap.h:795:5: note: template<class _Key, class _Tp, class _Compare, class _Alloc> bool std::operator==(const std::multimap<_Key, _Tp, _Compare, _Alloc>&, const std::multimap<_Key, _Tp, _Compare, _Alloc>&)
c:\mingw\bin\../lib/gcc/mingw32/4.6.2/include/c++/bits/stl_vector.h:1273:5: note: template<class _Tp, class _Alloc> bool std::operator==(const std::vector<_Tp, _Alloc>&, const std::vector<_Tp, _Alloc>&)
C:\Users\KiKo-SaMa\Desktop\C++\DVD_App\Customer.cpp:46:6: note: bool operator==(Customer&, Customer&)
C:\Users\KiKo-SaMa\Desktop\C++\DVD_App\Customer.cpp:46:6: note: no known conversion for argument 2 from 'const Customer' to 'Customer&'
c:\mingw\bin\../lib/gcc/mingw32/4.6.2/include/c++/bits/stl_algo.h:4403:45: instantiated from '_IIter std::find(_IIter, _IIter, const _Tp&) [with _IIter = __gnu_cxx::__normal_iterator<Customer*, std::vector<Customer> >, _Tp = Customer]'
C:\Users\KiKo-SaMa\Desktop\C++\DVD_App\Customer.cpp:42:66: instantiated from here
c:\mingw\bin\../lib/gcc/mingw32/4.6.2/include/c++/bits/stl_algo.h:166:4: error: no match for 'operator==' in '__first.__gnu_cxx::__normal_iterator<_Iterator, _Container>::operator* [with _Iterator = Customer*, _Container = std::vector<Customer>, __gnu_cxx::__normal_iterator<_Iterator, _Container>::reference = Customer&]() == __val'
c:\mingw\bin\../lib/gcc/mingw32/4.6.2/include/c++/bits/stl_algo.h:166:4: note: candidates are:
c:\mingw\bin\../lib/gcc/mingw32/4.6.2/include/c++/bits/postypes.h:218:5: note: template<class _StateT> bool std::operator==(const std::fpos<_StateT>&, const std::fpos<_StateT>&)
c:\mingw\bin\../lib/gcc/mingw32/4.6.2/include/c++/bits/stl_pair.h:201:5: note: template<class _T1, class _T2> bool std::operator==(const std::pair<_T1, _T2>&, const std::pair<_T1, _T2>&)
c:\mingw\bin\../lib/gcc/mingw32/4.6.2/include/c++/bits/stl_iterator.h:285:5: note: template<class _Iterator> bool std::operator==(const std::reverse_iterator<_Iterator>&, const std::reverse_iterator<_Iterator>&)
c:\mingw\bin\../lib/gcc/mingw32/4.6.2/include/c++/bits/stl_iterator.h:335:5: note: template<class _IteratorL, class _IteratorR> bool std::operator==(const std::reverse_iterator<_IteratorL>&, const std::reverse_iterator<_IteratorR>&)
c:\mingw\bin\../lib/gcc/mingw32/4.6.2/include/c++/bits/allocator.h:122:5: note: template<class _T1, class _T2> bool std::operator==(const std::allocator<_T1>&, const std::allocator<_T2>&)
c:\mingw\bin\../lib/gcc/mingw32/4.6.2/include/c++/bits/allocator.h:127:5: note: template<class _Tp> bool std::operator==(const std::allocator<_Tp1>&, const std::allocator<_Tp1>&)
c:\mingw\bin\../lib/gcc/mingw32/4.6.2/include/c++/bits/basic_string.h:2427:5: note: template<class _CharT, class _Traits, class _Alloc> bool std::operator==(const std::basic_string<_CharT, _Traits, _Alloc>&, const std::basic_string<_CharT, _Traits, _Alloc>&)
c:\mingw\bin\../lib/gcc/mingw32/4.6.2/include/c++/bits/basic_string.h:2434:5: note: template<class _CharT> typename __gnu_cxx::__enable_if<std::__is_char<_Tp>::__value, bool>::__type std::operator==(const std::basic_string<_CharT>&, const std::basic_string<_CharT>&)
c:\mingw\bin\../lib/gcc/mingw32/4.6.2/include/c++/bits/basic_string.h:2448:5: note: template<class _CharT, class _Traits, class _Alloc> bool std::operator==(const _CharT*, const std::basic_string<_CharT, _Traits, _Alloc>&)
c:\mingw\bin\../lib/gcc/mingw32/4.6.2/include/c++/bits/basic_string.h:2460:5: note: template<class _CharT, class _Traits, class _Alloc> bool std::operator==(const std::basic_string<_CharT, _Traits, _Alloc>&, const _CharT*)
c:\mingw\bin\../lib/gcc/mingw32/4.6.2/include/c++/bits/streambuf_iterator.h:194:5: note: template<class _CharT, class _Traits> bool std::operator==(const std::istreambuf_iterator<_CharT, _Traits>&, const std::istreambuf_iterator<_CharT, _Traits>&)
c:\mingw\bin\../lib/gcc/mingw32/4.6.2/include/c++/bits/stl_tree.h:309:5: note: template<class _Val> bool std::operator==(const std::_Rb_tree_iterator<_Tp>&, const std::_Rb_tree_const_iterator<_Val>&)
c:\mingw\bin\../lib/gcc/mingw32/4.6.2/include/c++/bits/stl_tree.h:846:5: note: template<class _Key, class _Val, class _KeyOfValue, class _Compare, class _Alloc> bool std::operator==(const std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>&, const std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>&)
c:\mingw\bin\../lib/gcc/mingw32/4.6.2/include/c++/bits/stl_map.h:877:5: note: template<class _Key, class _Tp, class _Compare, class _Alloc> bool std::operator==(const std::map<_Key, _Tp, _Compare, _Alloc>&, const std::map<_Key, _Tp, _Compare, _Alloc>&)
c:\mingw\bin\../lib/gcc/mingw32/4.6.2/include/c++/bits/stl_multimap.h:795:5: note: template<class _Key, class _Tp, class _Compare, class _Alloc> bool std::operator==(const std::multimap<_Key, _Tp, _Compare, _Alloc>&, const std::multimap<_Key, _Tp, _Compare, _Alloc>&)
c:\mingw\bin\../lib/gcc/mingw32/4.6.2/include/c++/bits/stl_vector.h:1273:5: note: template<class _Tp, class _Alloc> bool std::operator==(const std::vector<_Tp, _Alloc>&, const std::vector<_Tp, _Alloc>&)
C:\Users\KiKo-SaMa\Desktop\C++\DVD_App\Customer.cpp:46:6: note: bool operator==(Customer&, Customer&)
C:\Users\KiKo-SaMa\Desktop\C++\DVD_App\Customer.cpp:46:6: note: no known conversion for argument 2 from 'const Customer' to 'Customer&'
c:\mingw\bin\../lib/gcc/mingw32/4.6.2/include/c++/bits/stl_algo.h:170:4: error: no match for 'operator==' in '__first.__gnu_cxx::__normal_iterator<_Iterator, _Container>::operator* [with _Iterator = Customer*, _Container = std::vector<Customer>, __gnu_cxx::__normal_iterator<_Iterator, _Container>::reference = Customer&]() == __val'
c:\mingw\bin\../lib/gcc/mingw32/4.6.2/include/c++/bits/stl_algo.h:170:4: note: candidates are:
c:\mingw\bin\../lib/gcc/mingw32/4.6.2/include/c++/bits/postypes.h:218:5: note: template<class _StateT> bool std::operator==(const std::fpos<_StateT>&, const std::fpos<_StateT>&)
c:\mingw\bin\../lib/gcc/mingw32/4.6.2/include/c++/bits/stl_pair.h:201:5: note: template<class _T1, class _T2> bool std::operator==(const std::pair<_T1, _T2>&, const std::pair<_T1, _T2>&)
c:\mingw\bin\../lib/gcc/mingw32/4.6.2/include/c++/bits/stl_iterator.h:285:5: note: template<class _Iterator> bool std::operator==(const std::reverse_iterator<_Iterator>&, const std::reverse_iterator<_Iterator>&)
c:\mingw\bin\../lib/gcc/mingw32/4.6.2/include/c++/bits/stl_iterator.h:335:5: note: template<class _IteratorL, class _IteratorR> bool std::operator==(const std::reverse_iterator<_IteratorL>&, const std::reverse_iterator<_IteratorR>&)
c:\mingw\bin\../lib/gcc/mingw32/4.6.2/include/c++/bits/allocator.h:122:5: note: template<class _T1, class _T2> bool std::operator==(const std::allocator<_T1>&, const std::allocator<_T2>&)
c:\mingw\bin\../lib/gcc/mingw32/4.6.2/include/c++/bits/allocator.h:127:5: note: template<class _Tp> bool std::operator==(const std::allocator<_Tp1>&, const std::allocator<_Tp1>&)
c:\mingw\bin\../lib/gcc/mingw32/4.6.2/include/c++/bits/basic_string.h:2427:5: note: template<class _CharT, class _Traits, class _Alloc> bool std::operator==(const std::basic_string<_CharT, _Traits, _Alloc>&, const std::basic_string<_CharT, _Traits, _Alloc>&)
c:\mingw\bin\../lib/gcc/mingw32/4.6.2/include/c++/bits/basic_string.h:2434:5: note: template<class _CharT> typename __gnu_cxx::__enable_if<std::__is_char<_Tp>::__value, bool>::__type std::operator==(const std::basic_string<_CharT>&, const std::basic_string<_CharT>&)
Process terminated with status 1 (0 minutes, 1 seconds)
50 errors, 0 warnings
You should work on your const correctness, the problem is that your equality comparator takes the arguments by non const reference, but the last argument to find is taken by const reference, which means that the compiler cannot use it there.
Incidentally, once you add the const there you will be forced to add const accessors to the data. Also, if your operator only uses the public interface there is no need to declare it as a friend
CodeBlocks may give errors about the stl files however they are not actually the errors. It shows the related stl file of your error.

Problems using a map with a bitset as a key

I am trying to create a map in C++ with bitset as a key. However the compiler generates the following error messages
In file included from /usr/include/c++/4.6/string:50:0,
from /usr/include/c++/4.6/bits/locale_classes.h:42,
from /usr/include/c++/4.6/bits/ios_base.h:43,
from /usr/include/c++/4.6/ios:43,
from /usr/include/c++/4.6/ostream:40,
from /usr/include/c++/4.6/iostream:40,
from test2.cpp:1:
/usr/include/c++/4.6/bits/stl_function.h: In member function ‘bool std::less<_Tp>::operator()(const _Tp&, const _Tp&) const [with _Tp = std::bitset<8u>]’:
/usr/include/c++/4.6/bits/stl_map.h:452:2: instantiated from ‘std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](const key_type&) [with _Key = std::bitset<8u>, _Tp = int, _Compare = std::less<std::bitset<8u> >, _Alloc = std::allocator<std::pair<const std::bitset<8u>, int> >, std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type = int, std::map<_Key, _Tp, _Compare, _Alloc>::key_type = std::bitset<8u>]’
test2.cpp:22:30: instantiated from here
/usr/include/c++/4.6/bits/stl_function.h:236:22: error: no match for ‘operator<’ in ‘__x < __y’
/usr/include/c++/4.6/bits/stl_function.h:236:22: note: candidates are:
/usr/include/c++/4.6/bits/stl_pair.h:207:5: note: template<class _T1, class _T2> bool std::operator<(const std::pair<_T1, _T2>&, const std::pair<_T1, _T2>&)
/usr/include/c++/4.6/bits/stl_iterator.h:291:5: note: template<class _Iterator> bool std::operator<(const std::reverse_iterator<_Iterator>&, const std::reverse_iterator<_Iterator>&)
/usr/include/c++/4.6/bits/stl_iterator.h:341:5: note: template<class _IteratorL, class _IteratorR> bool std::operator<(const std::reverse_iterator<_IteratorL>&, const std::reverse_iterator<_IteratorR>&)
/usr/include/c++/4.6/bits/basic_string.h:2510:5: note: template<class _CharT, class _Traits, class _Alloc> bool std::operator<(const std::basic_string<_CharT, _Traits, _Alloc>&, const std::basic_string<_CharT, _Traits, _Alloc>&)
/usr/include/c++/4.6/bits/basic_string.h:2522:5: note: template<class _CharT, class _Traits, class _Alloc> bool std::operator<(const std::basic_string<_CharT, _Traits, _Alloc>&, const _CharT*)
/usr/include/c++/4.6/bits/basic_string.h:2534:5: note: template<class _CharT, class _Traits, class _Alloc> bool std::operator<(const _CharT*, const std::basic_string<_CharT, _Traits, _Alloc>&)
/usr/include/c++/4.6/bits/stl_tree.h:856:5: note: template<class _Key, class _Val, class _KeyOfValue, class _Compare, class _Alloc> bool std::operator<(const std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>&, const std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>&)
/usr/include/c++/4.6/bits/stl_set.h:713:5: note: template<class _Key, class _Compare, class _Alloc> bool std::operator<(const std::set<_Key, _Compare, _Alloc>&, const std::set<_Key, _Compare, _Alloc>&)
/usr/include/c++/4.6/bits/stl_multiset.h:696:5: note: template<class _Key, class _Compare, class _Alloc> bool std::operator<(const std::multiset<_Key, _Compare, _Alloc>&, const std::multiset<_Key, _Compare, _Alloc>&)
/usr/include/c++/4.6/bits/stl_map.h:894:5: note: template<class _Key, class _Tp, class _Compare, class _Alloc> bool std::operator<(const std::map<_Key, _Tp, _Compare, _Alloc>&, const std::map<_Key, _Tp, _Compare, _Alloc>&)
/usr/include/c++/4.6/bits/stl_multimap.h:812:5: note: template<class _Key, class _Tp, class _Compare, class _Alloc> bool std::operator<(const std::multimap<_Key, _Tp, _Compare, _Alloc>&, const std::multimap<_Key, _Tp, _Compare, _Alloc>&)
The progam code is given below
I am trying to use bitset as a key to a map in C++. However, everytime I run the code below I run into errros.
#include <iostream>
#include <algorithm>
#include <string>
#include <bitset>
#include <set>
#include <utility>
using namespace std;
int main(int argc, char *argv[])
{
bitset<8> test;
test = 9;
cout<<"Set to 9"<<endl;
map <bitset<8> , int> mymap;
pair <biset<8> , int> p;
p.first = test;
p.second = 9;
string teststring;
teststring = test.to_string<char,char_traits<char>,allocator<char> >();
cout<<teststring<<temymap[test]<<endl;
return 0;
}
Just use your own comparator class:
struct Comparer {
bool operator() (const bitset<8> &b1, const bitset<8> &b2) const {
return b1.to_ulong() < b2.to_ulong();
}
};
/* ... */
map <bitset<8> , int, Comparer> mymap;
Note that you can extend this solution to support arbitrary length bitsets, as long as they are small enough to be converted to an unsigned long:
template<size_t sz> struct bitset_comparer {
bool operator() (const bitset<sz> &b1, const bitset<sz> &b2) const {
return b1.to_ulong() < b2.to_ulong();
}
};
map <bitset<8> , int, bitset_comparer<8> > mymap;
map <bitset<16> , int, bitset_comparer<16> > mymap16;
An alternative solution would be to simply use an unordered_map, if this still meets your requirements.
This could be std::unordered_map<bitset<N>, T> or boost::unordered_map<bitset<N>, T>, depending on C++ version or performance considerations.
This avoids the need for comparison and may prove faster, depending on requirements.
You can define your comparison function. If you assume your bitset models an unsigned integral value then the following function will order the bitsets in increasing order (and works for any N).
template <size_t N>
class LessThan {
public:
bool operator() (const std::bitset<N> &lhs, const std::bitset<N> &rhs) const
{
size_t i = N;
while ( i > 0 ) {
if ( lhs[i-1] == rhs[i-1] ) {
i--;
} else if ( lhs[i-1] < rhs[i-1] ) {
return true;
} else {
return false;
}
}
return false;
}
};
If you run the following snippet:
const size_t mysz = 10;
std::map< std::bitset<mysz>, size_t, Less<mysz> > mymap;
for ( size_t i = 0; i < 10; i++ ) {
mymap.insert( std::make_pair(std::bitset<mysz>(i),i) );
}
You will have this map:
mymap[0] is the pair ((0,0,0,0,0,0,0,0,0,0), 0)
mymap[1] is the pair ((1,0,0,0,0,0,0,0,0,0), 1)
mymap[2] is the pair ((0,1,0,0,0,0,0,0,0,0), 2)
mymap[3] is the pair ((1,1,0,0,0,0,0,0,0,0), 3)
mymap[4] is the pair ((0,0,1,0,0,0,0,0,0,0), 4)
mymap[5] is the pair ((1,0,1,0,0,0,0,0,0,0), 5)
mymap[6] is the pair ((0,1,1,0,0,0,0,0,0,0), 6)
mymap[7] is the pair ((1,1,1,0,0,0,0,0,0,0), 7)
mymap[8] is the pair ((0,0,0,1,0,0,0,0,0,0), 8)
mymap[9] is the pair ((1,0,0,1,0,0,0,0,0,0), 9)
This will allow map<bitset<N>,int> stuff directly:
namespace std{
template<size_t N>
struct less<bitset<N> > : binary_function <bitset<N>,bitset<N>,bool>{
bool operator()(const bitset<N> &L, const bitset<N> &R) const{
for(unsigned int i=0;i<L.size();i++)
if(L.test(i)){
if(!R.test(i))return false;
}else{
if(R.test(i))return true;
}
return false; //same
}
};
}
For storing in the map you can convert bitset to string for large bitset if it's not convertible to u_long and for updating you can change back to bitset and do your changes and store back as a string.
map<string , int> mymap;
bitset<N> mybs("10100"); // converting string to bitset
map[mybs.to_string()] = 34; // bitset to string for map
This is valid as long as you don't care about the comparison.