std vector no match for operator == - c++

I'm stuck at this error:
gcc.compile.c++
Physics/HelicityAmplitude/bin/gcc-4.8.3/debug/HelicityDecayTree.o In
file included from
/cvmfs/cluster/gcc/gcc-4.8.3/include/c++/4.8.3/algorithm:62:0,
from /cluster/compwa_externals/boost_1_55_0/include/boost/move/algorithm.hpp:23,
from /cluster/compwa_externals/boost_1_55_0/include/boost/move/move.hpp:24,
from /cluster/compwa_externals/boost_1_55_0/include/boost/unordered/detail/util.hpp:19,
from /cluster/compwa_externals/boost_1_55_0/include/boost/unordered/detail/buckets.hpp:14,
from /cluster/compwa_externals/boost_1_55_0/include/boost/unordered/detail/table.hpp:10,
from /cluster/compwa_externals/boost_1_55_0/include/boost/unordered/detail/equivalent.hpp:14,
from /cluster/compwa_externals/boost_1_55_0/include/boost/unordered/unordered_set.hpp:17,
from /cluster/compwa_externals/boost_1_55_0/include/boost/unordered_set.hpp:16,
from /cluster/compwa_externals/boost_1_55_0/include/boost/graph/adjacency_list.hpp:21,
from Physics/HelicityAmplitude/HelicityDecayTree.hpp:17,
from Physics/HelicityAmplitude/HelicityDecayTree.cpp:12:
/cvmfs/cluster/gcc/gcc-4.8.3/include/c++/4.8.3/bits/stl_algo.h: In
instantiation of ‘_RandomAccessIterator
std::__find(_RandomAccessIterator, _RandomAccessIterator, const _Tp&,
std::random_access_iterator_tag) [with _RandomAccessIterator =
__gnu_cxx::__normal_iterator >; _Tp =
HelicityFormalism::ParticleState]’:
/cvmfs/cluster/gcc/gcc-4.8.3/include/c++/4.8.3/bits/stl_algo.h:4441:45:
required from ‘_IIter std::find(_IIter, _IIter, const _Tp&) [with
_IIter = __gnu_cxx::__normal_iterato r >; _Tp =
HelicityFormalism::ParticleState]’
Physics/HelicityAmplitude/HelicityDecayTree.cpp:59:61: required from
here
/cvmfs/cluster/gcc/gcc-4.8.3/include/c++/4.8.3/bits/stl_algo.h:166:17:
error: no match for ‘operator==’ (operand types are
‘HelicityFormalism::ParticleState’ and ‘const Helicit
yFormalism::ParticleState’)
if (*__first == __val)
I see that he is asking for a const to non-const comparison of ParticleState. However I don't really understand why he is asking for this comparison. My relevant code is the following:
The header for the class:
class HelicityDecayTree {
boost::adjacency_list<> decay_tree_;
std::vector<ParticleState> particles_;
public:
void createDecay(const ParticleState &mother,
const ParticleStatePair &daughters);
}
And the source for that member function:
void HelicityDecayTree::createDecay(const ParticleState &mother,
const ParticleStatePair &daughters) {
// add particles to the list
unsigned int mother_vector_index;
unsigned int daughter1_vector_index;
unsigned int daughter2_vector_index;
if (std::find(particles_.begin(), particles_.end(), mother)
== particles_.end()) {
mother_vector_index = particles_.size();
particles_.push_back(mother);
}
else {
mother_vector_index = std::distance(particles_.begin(),
std::find(particles_.begin(), particles_.end(), mother));
}
if (std::find(particles_.begin(), particles_.end(), daughters.first)
== particles_.end()) {
daughter1_vector_index = particles_.size();
particles_.push_back(daughters.first);
}
else {
daughter1_vector_index = std::distance(particles_.begin(),
std::find(particles_.begin(), particles_.end(), daughters.first));
}
if (std::find(particles_.begin(), particles_.end(), daughters.second)
== particles_.end()) {
daughter2_vector_index = particles_.size();
particles_.push_back(daughters.second);
}
else {
daughter2_vector_index = std::distance(particles_.begin(),
std::find(particles_.begin(), particles_.end(), daughters.second));
}
// then make the correct inserts into the vector and link appropriately
boost::add_edge(mother_vector_index, daughter1_vector_index, decay_tree_);
boost::add_edge(mother_vector_index, daughter2_vector_index, decay_tree_);
}
And the ParticleState struct:
struct ParticleState {
int particle_id_;
std::string name_;
Spin J_;
Spin M_;
};
Afaiu he should be synthesizing the operator== for two const ParticleStates, but for some reason the find method is asking for a non-const version for 1 argument...
Thx in advance,
Steve

Ok I forgot that the compiler will not synthesize the operator==. So I was just missing
bool operator==(const ParticleState &rhs) const {
...
}

Related

Overloaded template operator calling separate class operator

I've got a template class containing a priority queue of other classes, I need to use the priority overloader to call the individual class overloaders to compare based on the individual classes preferences (in this case it's age, in another class it could be price.
I've got absolutely no doubt that I've implemented the operator overloading incorrect so would appreciate the advice.
For example
#include <iostream>
#include <queue>
#include <string>
using namespace std;
class Animal {
public:
Animal();
Animal(string t, int a);
int get_age()const;
bool operator< ( Animal& b) const;
void display()const;
private:
string type;
double age;
};
void Animal::display() const
{
cout << "Type: " << type << " Age: " << age;
}
int Animal::get_age() const
{
return age;
}
Animal::Animal(){}
Animal::Animal(string t, int a)
{
type = t;
age = a;
}
bool Animal::operator< ( Animal& b) const
{
return b.get_age();
}
template<typename T>
class Collection {
public:
Collection();
Collection(string n, string d);
void add_item(const T& c);
private:
priority_queue <T> pets;
string name; // Name of the collection
string description; // Descriptions of the collection
};
template<typename T>
Collection<T>::Collection(){}
template<typename T>
Collection<T>::Collection(string n, string d)
{
name = n;
description = d;
}
template<typename T>
bool operator<(const T& one, const T& two)
{
return one.operator<(two);
}
template<typename T>
void Collection<T>::add_item(const T& c)
{
pets.push(c);
}
int main(){
Animal p1("Dog", 10);
Animal p2("Cat", 5);
Animal p3("Turtle", 24);
Collection<Animal> P("Pets", "My Pets");
P.add_item(p1);
P.add_item(p2);
P.add_item(p3);
cout << endl;
return 0;
}
I get this error and I'm not sure what I need to do to fix it. I've got to keep the class overloader as the single variable (Animal& b).
task.cpp: In instantiation of 'bool operator<(const T&, const T&)
[with T = Animal]':
c:\mingw-4.7.1\bin../lib/gcc/mingw32/4.7.1/include/c++/bits/stl_function.h:237:22:
required from 'bool std::less<_Tp>::operator()(const _Tp&, const _Tp&)
const [with _Tp = Animal]'
c:\mingw-4.7.1\bin../lib/gcc/mingw32/4.7.1/include/c++/bits/stl_heap.h:310:4: required from 'void std::__adjust_heap(_RandomAccessIterator,
_Distance, _Distance, _Tp, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator > >; _Distance = int; _Tp = Animal; _Compare =
std::less]'
c:\mingw-4.7.1\bin../lib/gcc/mingw32/4.7.1/include/c++/bits/stl_heap.h:442:4: required from 'void std::make_heap(_RandomAccessIterator,
_RandomAccessIterator, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator > >; _Compare = std::less]'
c:\mingw-4.7.1\bin../lib/gcc/mingw32/4.7.1/include/c++/bits/stl_queue.h:393:9: required from 'std::priority_queue<_Tp, _Sequence,
_Compare>::priority_queue(const _Compare&, const _Sequence&) [with _Tp = Animal; _Sequence = std::vector >; _Compare = std::less]' task.cpp:57:45: required from 'Collection::Collection(std::string, std::string) [with T = Animal;
std::string = std::basic_string]' task.cpp:79:43: required
from here task.cpp:66:30: error: no matching function for call to
'Animal::operator<(const Animal&) const' task.cpp:66:30: note:
candidate is: task.cpp:36:6: note: bool Animal::operator<(Animal&)
const task.cpp:36:6: note: no known conversion for argument 1 from
'const Animal' to 'Animal&' task.cpp: In function 'bool
operator<(const T&, const T&) [with T = Animal]':
Your comparison
bool Animal::operator< ( Animal& b) const
{
return b.get_age(); // returns true always unless age == 0
}
is no comparison and it should take a const parameter. You should have something like
bool Animal::operator< (const Animal& b) const
// ^----------------------- const !
{
return get_age() < b.get_age();
}
Btw you dont need to use a member operator< for the priority queue. Especially if you want to sort objects in different ways I would recommend to not use it, but pass a lambda to the priority_queue. See eg here for an example.
Both of your overloads of < are problematic
bool Animal::operator< ( Animal& b) const
the Animal should also be const. You also need to compare both parameters, otherwise things (such as your priority_queue) that expect < to provide an ordering will have undefined behaviour.
You don't use anything non-public from Animal, so I suggest you change it to
bool operator< (const Animal & lhs, const Animal & rhs)
{ return lhs.get_age() < rhs.get_age(); }
This has the benefit of treating both sides identically, rather than one being implicit.
template<typename T>
bool operator<(const T& one, const T& two)
{
return one.operator<(two);
}
This template matches all types and is entirely superfluous. a < b can call either a member or a free operator <. Just delete this template.

Can't remove element by ID from vector of non primitive datatypes

I have a vector of my user-defined data type city. I'm trying to remove an element from this vector by its ID; eventually all cities will be removed from this list in a while(!cityList.empty()) loop. I plan to use the erase-remove idiom to accomplish this.
However, I'm getting a very gnarly error message when I make my code after calling remove(). Passing in the city object as the third parameter to remove() results in this error, as does passing in the (int) ID of the city. This error doesn't occur with erase(), but does with remove(), and also find() if I try to use that. Here is the code in question:
vector<city> cityList;
cityList.push_back(city(1));
cityList.push_back(city(2));
cityList.push_back(city(3));
city cityToRemove = cityList[0];
int idOfCityToRemove = cityList[0].getID();
remove(cityList.begin(), cityList.end(), cityToRemove);
//remove(cityList.begin(), cityList.end(), idOfCityToRemove);
Here is an updated simple, minimal demo of my problem.
The error message includes "template argument deduction/substitution failed" and "‘city’ is not derived from ‘const _gnu_cxx::__normal_iterator<_IteratorL, _Container>’ " messages, and I haven't been able to find anything online relating to my problem with the above errors.
Edit: I've modified my code such that I now have:
int main(int argc, char** argv) {
vector<city> cityList;
cityList.push_back(city(1));
cityList.push_back(city(2));
cityList.push_back(city(3));
city cityToRemove = cityList[0];
int idOfCityToRemove = cityList[0].getID();
int i;
for (i = 0; i < cityList.size(); i++) {
cityList.erase(remove_if(cityList.begin(), cityList.end(), cityList[i] == cityToRemove), cityList.end());
}
//remove(cityList.begin(), cityList.end(), cityToRemove);
//remove(cityList.begin(), cityList.end(), idOfCityToRemove);
return 0;
}
bool operator ==(const city &a, const city &b)
{
return (a.id == b.id);
}
and the error I receive when attempting to compile is:
In file included from /usr/include/c++/5/bits/stl_algobase.h:71:0,
from /usr/include/c++/5/bits/char_traits.h:39,
from /usr/include/c++/5/ios:40,
from /usr/include/c++/5/ostream:38,
from /usr/include/c++/5/iostream:39,
from main.cpp:2:
/usr/include/c++/5/bits/predefined_ops.h: In instantiation of ‘bool __gnu_cxx::__ops::_Iter_pred<_Predicate>::operator()(_Iterator) [with _Iterator = __gnu_cxx::__normal_iterator<city*, std::vector<city> >; _Predicate = bool]’:
/usr/include/c++/5/bits/stl_algo.h:866:20: required from _ForwardIterator std::__remove_if(_ForwardIterator, _ForwardIterator, _Predicate) [with _ForwardIterator = __gnu_cxx::__normal_iterator<city*, std::vector<city> >; _Predicate = __gnu_cxx::__ops::_Iter_pred<bool>]’
/usr/include/c++/5/bits/stl_algo.h:936:30: required from ‘_FIter std::remove_if(_FIter, _FIter, _Predicate) [with _FIter = __gnu_cxx::__normal_iterator<city*, std::vector<city> >; _Predicate = bool]’
main.cpp:30:90: required from here
/usr/include/c++/5/bits/predefined_ops.h:234:30: error: expression cannot be used as a function
{ return bool(_M_pred(*__it)); }
^
This is closer, but I'm not sure what is required. The line main.cpp:30:90 points to the cityList[i] == cityToRemove part of my cityList.erase() function, however, so I know that the issue is within my comparison expression.
My demo is also updated.
You need to define an operator ==:
class city {
public:
city(int idin);
int getID();
private:
int id;
friend bool operator==(const city &a, const city &b);
};
.
bool operator ==(const city &a, const city &b)
{
return a.id == b.id;
}
and also call erase as in the example here.

Error is generated with the sort method while sorting the values inside a vector

When we are compiling the below code using g++ in debian machine, then following errors are generated...can anyone pls help me why the error are? I tried by commenting sort line then error dissappears however our task requires sorting to be done then what can be the possible solution
Code:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
// Here is a simple struct
struct MyStruct
{
int Num;
// Define the operator <
bool operator <(const MyStruct& Rhs)
{
return (Num < Rhs.Num);
}
};
int main()
{
vector<MyStruct> MyVector;
// Let the size be 5.
MyVector.resize(5);
// Push 5 instances of MyStruct with Num ranging
// from 5 to 1
MyStruct TestStruct;
int i = 0;
for (i = 0; i < 5; ++i)
{
TestStruct.Num = 5 - i;
MyVector[i] = TestStruct;
}
// Now sort the vector
sort(MyVector.begin(), MyVector.end());
// Try to display Num for each element. It is sorted
for (i = 0; i < 5; ++i)
{
cout << MyVector[i].Num << '\n';
}
return 0;
}
Output:
In file included from /usr/include/c++/4.7/algorithm:63:0,
from testvect.cpp:3: /usr/include/c++/4.7/bits/stl_algo.h: In instantiation of
‘_RandomAccessIterator
std::__unguarded_partition(_RandomAccessIterator,
_RandomAccessIterator, const _Tp&) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator >; _Tp = MyStruct]’: /usr/include/c++/4.7/bits/stl_algo.h:2309:70: required
from ‘_RandomAccessIterator
std::__unguarded_partition_pivot(_RandomAccessIterator,
_RandomAccessIterator) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator >]’ /usr/include/c++/4.7/bits/stl_algo.h:2340:54: required from ‘void
std::__introsort_loop(_RandomAccessIterator, _RandomAccessIterator,
_Size) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator >; _Size = int]’ /usr/include/c++/4.7/bits/stl_algo.h:5476:4: required from ‘void std::sort(_RAIter, _RAIter) [with _RAIter =
__gnu_cxx::__normal_iterator >]’ testvect.cpp:33:41: required from here
/usr/include/c++/4.7/bits/stl_algo.h:2271:4: error: passing ‘const
MyStruct’ as ‘this’ argument of ‘bool MyStruct::operator<(const
MyStruct&)’ discards qualifiers [-fpermissive]
You use quite dated compiler where stl used const& parameters, in more modern versions those are passed by rvalue references and does not require const operator<, so to fix it:
Change:
bool operator <(const MyStruct& Rhs)
to
bool operator <(const MyStruct& Rhs) const
^^^^^
Alternately, use a later version of the compiler which supports more modern versions of C++ and then enable the more modern versions with '-std=c++11' or '-std=c++14'.
Corrected Code:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
// Here is a simple struct
struct MyStruct
{
int Num;
// Define the operator <
bool operator <(const MyStruct& Rhs)const
{
return (Num < Rhs.Num);
}
};
int main()
{
vector<MyStruct> MyVector;
// Let the size be 5.
MyVector.resize(5);
// Push 5 instances of MyStruct with Num ranging
// from 5 to 1
MyStruct TestStruct;
int i = 0;
for (i = 0; i < 5; ++i)
{
TestStruct.Num = 5 - i;
MyVector[i] = TestStruct;
}
// Now sort the vector
sort(MyVector.begin(), MyVector.end());
// Try to display Num for each element. It is sorted
for (i = 0; i < 5; ++i)
{
cout << MyVector[i].Num << '\n';
}
return 0;

Sorting vector of Pointers of Custom Class

I have vector<FPGA*> current_generation_, which I'd like to sort by FPGA member fitness_ using the sort_members function. Applicable code follows:
bool sort_members (FPGA* fpga_first, FPGA* fpga_second) {
return (fpga_first->fitness() < fpga_second->fitness());
};
fpga.hpp
#include <vector>
class FPGA {
public:
explicit FPGA(int input_gates, int output_gates, int normal_gates);
const int fitness();
protected:
int fitness_;
};
fpga.cpp
FPGA::FPGA() {
this->fitness_ = 0;
}
const int FPGA::fitness() {
return this->fitness_;
}
implementation:
std::sort(this->current_generation_.begin(), this->current_generation_.end(), sort_members);
errors:
/usr/include/c++/4.9/bits/stl_algo.h: In instantiation of ‘void std::__sort(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = std::__detail::_Node_iterator<std::pair<const int, FPGA*>, false, false>; _Compare = __gnu_cxx::__ops::_Iter_comp_iter<bool (*)(FPGA*, FPGA*)>]’:
/usr/include/c++/4.9/bits/stl_algo.h:4717:78: required from ‘void std::sort(_RAIter, _RAIter, _Compare) [with _RAIter = std::__detail::_Node_iterator<std::pair<const int, FPGA*>, false, false>; _Compare = bool (*)(FPGA*, FPGA*)]’
/usr/include/c++/4.9/bits/stl_algo.h:1968:22: error: no match for ‘operator-’ (operand types are ‘std::__detail::_Node_iterator<std::pair<const int, FPGA*>, false, false>’ and ‘std::__detail::_Node_iterator<std::pair<const int, FPGA*>, false, false>’)
std::__lg(__last - __first) * 2,
The remainder of the total error string is huge, but I believe is mostly what the compiler believes(falsely) are candidates. I'm not extremely familiar with c++, and a compiler error of this magnitude and complexity is confusing to me.
I can provide more context if needed. Thanks!
EDIT: A dash.
EDIT EDIT: I screwed up, and was trying to sort the wrong member. Hooray.
The only error that I see is this>current_generation_.end() instead that ->.
In addition you should consider declaring your compare fuction as accepting two const FPGA* instead that just FPGA*. This will force you to declare fitness() as const int fitness() const but it makes sense to have it const.
Mind that since you are using C++11 you can directly use a lambda:
std::sort(data.begin(), data.end(), [](const FPGA* f1, const FPGA* f2) { ... });
You also have the choice to overload operator< directly:
class FPGA {
...
bool operator<(const FPGA* other) const { return fitness_ < other->fitness_; }
}
std::sort(data.begin(), data.end());
This could be useful if it doesn't make sense to have other criteria to compare two FPGA instances since you add some semantics to the object itself.

Modifying set elements

With the below code, I am trying to update the values in a set but its not compiling when i try to compile .
It's giving me the error at the bottom, can you please help ?
What wrong I am doing here?
#include < iostream >
#include < set >
using namespace std;
class A
{
public:
int a,b;
bool operator()(A a1,A a2)
{
return true;
}
A(int a ,int b)
{
this.a=a;
this.b=b;
}
};
void print_set(const std::set<A>&st) const
{
std::set<A>::iterator it;
std::cout<<"\nvalues in set";
for(it=st.begin();it!=st.end();it++)
{
std::cout<<"\na="<<it->a<<"b="<<it->b;
}
}
int main ()
{
std::set<A> s;
for ( int i=0;i<5;i++)
{
s.insert(A(i,i+1));
}
print_set(s);
std::set<A>::iterator it;
for(it=s.begin();it!=s.end();it++)
{
A tmp=*it;
s.erase(it);
tmp.a=10;
tmp.b=20;
s.insert(tmp);
std::cout<<"\ninserting tmp "<<tmp.a<<" "<<tmp.b;
}
print_set(s);
return 0;
}
I am getting an error like this :
/usr/include/c++/4.6/bits/stl_function.h: In member function ‘bool std::less<_Tp>::operator()(const _Tp&, const _Tp&) const [with _Tp = A]’:
/usr/include/c++/4.6/bits/stl_tree.h:1277:4: instantiated from ‘std::pair<std::_Rb_tree_iterator<_Val>, bool> std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_insert_unique(const _Val&) [with _Key = A, _Val = A, _KeyOfValue = std::_Identity<A>, _Compare = std::less<A>, _Alloc = std::allocator<A>]’
A few issues in your code, see below comments:
A(int a ,int b)
{
//this.a=a;
//this.b=b;
this->a = a; // this pointer should be accessed by this->
this->b = b;
}
// to store element in std::set, it must follow strict weak ordering rule.
// by default, operator< need to be defined
bool operator<(const A& lhs, const A& rhs)
{
return lhs.a < rhs.a;
}
// print_set is not a member function, can't have trailing const after function name
void print_set(const std::set<A>&st) // const