Errors risen on std::find over a vector of objects - c++

In this function I would like to search 'vertex' in the vector queue.
bool PriorityQueue::contains(VertexPriority vertex) const {
return (std::find(queue.begin(), queue.end(), vertex) != queue.end());
}
The vector queue is an instance of this object:
std::vector<VertexPriority> queue;
And my operator overloading is this:
bool operator==(const VertexPriority& v){ return (v.vertex == vertex); }
How can I solve this error?
The errors risen are the next ones, and at the beginning of every error there is the following path:
C:\Dev-Cpp\include\c++\3.4.2\bits\stl_algo.h
In function `_RandomAccessIterator std::find(_RandomAccessIterator, _RandomAccessIterator, const _Tp&, std::random_access_iterator_tag) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator > >, _Tp = VertexPriority]':
instantiated from `_InputIterator std::find(_InputIterator, _InputIterator, const _Tp&) [with _InputIterator = __gnu_cxx::__normal_iterator > >, _Tp = VertexPriority]'
passing const VertexPriority' asthis' argument of `bool VertexPriority::operator==(const VertexPriority&)' discards qualifiers

Make the operator const:
bool operator==(const VertexPriority& v) const
{
return (v.vertex == vertex);
}
Note that this makes the member function const itself, which enables the compiler to invoke it on a const object of VertexPriority type.
This is actually precisely what the compiler sais:
passing const VertexPriority' as this' argument of `bool VertexPriority::operator==(const VertexPriority&)' discards qualifiers
The VertexPriority object that is const, is being passed as the implicit thisargument to member functions.

Related

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

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

compilation error ::vector ::iteratator

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

Why I can't define compare without constant

If I define my compare function like this:
bool compare(Student& a, Student& b)
{
return a.n < b.n;
}
g++ will complain:
g++ -Wall main.cpp -o main
In file included from /usr/lib/gcc/x86_64-pc-linux-gnu/4.5.3/include/g++-v4/algorithm:63:0,
from main.cpp:1:
/usr/lib/gcc/x86_64-pc-linux-gnu/4.5.3/include/g++-v4/bits/stl_algo.h: In function ‘_RandomAccessIterator std::__unguarded_partition(_RandomAccessIterator, _RandomAccessIterator, const _Tp&, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<Student*, std::vector<Student> >, _Tp = Student, _Compare = bool (*)(Student&, Student&)]’:
/usr/lib/gcc/x86_64-pc-linux-gnu/4.5.3/include/g++-v4/bits/stl_algo.h:2261:78: instantiated from ‘_RandomAccessIterator std::__unguarded_partition_pivot(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<Student*, std::vector<Student> >, _Compare = bool (*)(Student&, Student&)]’
/usr/lib/gcc/x86_64-pc-linux-gnu/4.5.3/include/g++-v4/bits/stl_algo.h:2302:62: instantiated from ‘void std::__introsort_loop(_RandomAccessIterator, _RandomAccessIterator, _Size, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<Student*, std::vector<Student> >, _Size = long int, _Compare = bool (*)(Student&, Student&)]’
/usr/lib/gcc/x86_64-pc-linux-gnu/4.5.3/include/g++-v4/bits/stl_algo.h:5250:4: instantiated from ‘void std::sort(_RAIter, _RAIter, _Compare) [with _RAIter = __gnu_cxx::__normal_iterator<Student*, std::vector<Student> >, _Compare = bool (*)(Student&, Student&)]’
main.cpp:38:51: instantiated from here
/usr/lib/gcc/x86_64-pc-linux-gnu/4.5.3/include/g++-v4/bits/stl_algo.h:2229:4: error: invalid initialization of reference of type ‘Student&’ from expression of type ‘const Student’
/usr/lib/gcc/x86_64-pc-linux-gnu/4.5.3/include/g++-v4/bits/stl_algo.h:2232:4: error: invalid initialization of reference of type ‘Student&’ from expression of type ‘const Student’
Compilation exited abnormally with code 1 at Mon May 28 08:05:35
But if I define the compare with const type, it will compile and works fine.
And here is all the code:
class Student {
public:
Student(string);
string n;
};
bool compare(Student& a, Student& b)
{
return a.n < b.n;
}
Student::Student(string name) { n = name; }
int main()
{
Student A = Student("A");
Student B = Student("B");
vector<Student> students;
students.push_back(B);
students.push_back(A);
sort(students.begin(), students.end(), compare);
cout << "After sort" << endl;
for(vector<Student>::iterator i = students.begin(); i != students.end(); ++i) {
cout << "Student: " << i->n << endl;
}
return 0;
}
In this implementation, std::sort uses
const _Tp& std::__median(const _Tp&, const _Tp&, const _Tp&, _Compare);
In your case, _Tp is student, and _Compare is compare.
So you basically have
const Student& std::__median(const Student&, const Student&, const Student&,
bool (*)(Student&, Student&) )
or similar. Obviously, the callback can't be applied to the parameters are they are converted to const, so the failure.
Make the parameters to your compare method const.
I don't believe there is a requirement in the standard that says the parameters to the function must be const, so I believe your implementation is in error for rejecting it. However, there is a requirement that the function not modify the arguments:
From the standard -- 25.4/2
Compare is a function object type (20.8). The return value of the
function call operation applied to an object of type Compare, when
contextually converted to bool (4), yields true if the first argument
of the call is less than the second, and false otherwise. Compare comp
is used throughout for algorithms assuming an ordering relation. It is
assumed that comp will not apply any non-constant function through the
dereferenced iterator.
And the signature of std::sort from 25.4.1.1
template<class RandomAccessIterator, class Compare>
void sort(RandomAccessIterator first, RandomAccessIterator last, Compare comp)
So since your function is not allowed to modify its arguments, it really should be taking them in as const, but the standard does not require that. So while your implementation may be in error, I believe it is a forgivable error, as it manages to call attention to the fact that either your function is in violation of the standard by modifying its arguments, or it is not const-correct.
You should make it const since it leaves the two parameters the same.

C++ Call pointer to member with a map from a const function

I have a map of pointer to member declared as :
std::map<char, T (Operand::*)(const T &, const T &)> op_map;
I fill my map with pointer to member directly in the constructor of my class with :
op_map['+'] = &Operand::op_add;
For example, op_add source code is :
T op_add(const T & a, const T & b) {
return a + b;
}
And I want to call my pointer to member from a const function. Here is the source code :
IOperand *res_int32(char op, const IOperand & rhs) const {
IOperand *res = const_cast<IOperand *>(&rhs);
Operand<int> *tmp = dynamic_cast<Operand<int>*>(res);
T res_calc = (this->*op_map[op])(_value, (T)tmp->getValue());
}
But it makes me always an error :
Operand.hpp:70:64: error: passing ‘const std::map<char, double (Operand<double>::*)(const double&, const double&), std::less<char>, std::allocator<std::pair<const char, double (Operand<double>::*)(const double&, const double&)> > >’ as ‘this’ argument of ‘std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](const key_type&) [with _Key = char, _Tp = double (Operand<double>::*)(const double&, const double&), _Compare = std::less<char>, _Alloc = std::allocator<std::pair<const char, double (Operand<double>::*)(const double&, const double&)> >, std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type = double (Operand<double>::*)(const double&, const double&), std::map<_Key, _Tp, _Compare, _Alloc>::key_type = char]’ discards qualifiers [-fpermissive]
Operand.hpp:70:64: error: invalid conversion from ‘const Operand<double>* const’ to ‘Operand<double>*’ [-fpermissive]
Have you got any solution ?
Thank you.
operator[] can't be applied to a const map, since it inserts a new element if the key is not found.
In C++11, there is an at function which throws an exception if the key is not found:
T res_calc = (this->*op_map.at(op))(_value, (T)tmp->getValue());
^^^^^^^
In C++03, you'll need to use find:
map_type::const_iterator found = op_map.find(op);
if (found != op_map.end()) {
T res_calc = (this->*(found->second))(_value, (T)tmp->getValue());
} else {
// handle error
}
You'll also need to change the type of the member functions in the map to
T (Operand::*)(const T &, const T &) const
^^^^^
in order to call them on this from a const member function.
Just make op_add a const member function.
T op_add(const T & a, const T & b) const // <<<
{
return a + b;
}
And instead of the std::map::operator[] use std::map::find http://www.cplusplus.com/reference/stl/map/find/
EDIT:
You also need to change the map type to std::map<char, T (Operand::*)(const T &, const T &) const> op_map, as correctly pointed by R. Martinho Fernandes.
If you know what you are doing, you can try to compile with the c++ flag -fpermissive as G++ said.

STL Sort on nested Classes

I have a graph class that has a vector of nodes. In each node, there is a vertex and a STL list of edges. Essentially it's an adjacency list.
For my assignment, I am trying to display the vertices with the most edges. I figured I would sort the graph's vector of nodes by edge size and print the top N vertices.
So I am trying to figure out STL sort, but I'm having difficulties.
I have
std::sort(path.begin(), path.end());
Where path is the vector of nodes (node = vertex value and list of edges)
In my node class, I have
bool operator<(const Node<T>& rhs){
return size < rhs.size; //size is how many edges the vertex has
}
But it's giving me errors. How can I construct the operator< function in my node class to work with STL sort?
Here are the errors:
$ make
g++ -c -g -std=c++0x graphBuilder.cpp
In file included from /usr/lib/gcc/i486-slackware-linux/4.5.2/../../../../include/c++/4.5.2/algorithm:63:0,
from graph.h:6,
from graphBuilder.cpp:2:
/usr/lib/gcc/i486-slackware-linux/4.5.2/../../../../include/c++/4.5.2/bits/stl_algo.h: In function '_RandomAccessIterator std::__unguarded_partition(_RandomAccessIterator, _RandomAccessIterator, const _Tp&) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<Node<std::basic_string<char> >*, std::vector<Node<std::basic_string<char> >, std::allocator<Node<std::basic_string<char> > > > >, _Tp = Node<std::basic_string<char> >]':
/usr/lib/gcc/i486-slackware-linux/4.5.2/../../../../include/c++/4.5.2/bits/stl_algo.h:2249:70: instantiated from '_RandomAccessIterator std::__unguarded_partition_pivot(_RandomAccessIterator, _RandomAccessIterator) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<Node<std::basic_string<char> >*, std::vector<Node<std::basic_string<char> >, std::allocator<Node<std::basic_string<char> > > > >]'
/usr/lib/gcc/i486-slackware-linux/4.5.2/../../../../include/c++/4.5.2/bits/stl_algo.h:2280:54: instantiated from 'void std::__introsort_loop(_RandomAccessIterator, _RandomAccessIterator, _Size) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<Node<std::basic_string<char> >*, std::vector<Node<std::basic_string<char> >, std::allocator<Node<std::basic_string<char> > > > >, _Size = int]'
/usr/lib/gcc/i486-slackware-linux/4.5.2/../../../../include/c++/4.5.2/bits/stl_algo.h:5212:4: instantiated from 'void std::sort(_RAIter, _RAIter) [with _RAIter = __gnu_cxx::__normal_iterator<Node<std::basic_string<char> >*, std::vector<Node<std::basic_string<char> >, std::allocator<Node<std::basic_string<char> > > > >]'
graph.h:32:13: instantiated from 'void Graph<T>::topN(int) [with T = std::basic_string<char>]'
graphBuilder.cpp:10:17: instantiated from here /usr/lib/gcc/i486-slackware-linux/4.5.2/../../../../include/c++/4.5.2/bits/stl_algo.h:2211:4: error: passing 'const Node<std::basic_string<char> >' as 'this' argument of 'bool Node<T>::operator<(const Node<T>&) [with T = std::basic_string<char>]' discards qualifiers
make: *** [graphBuilder.o] Error 1
Your member function needs to be const-qualified:
bool operator<(const Node<T>& rhs) const{
EDIT
Per request, here is a bit more how I knew that you needed to make the member function const.
Divining the hidden meanings in stdlib-related compiler errors is something of an art, and something that you get better at with practice. Stdlib-related errors will often emit a whole series of compiler errors. Usually the most useful of these errors is the last one, because that one is generated from the context of the code you actually wrote, rather than coming from the bowels of the library code.
In this case, the last compiler error was:
graphBuilder.cpp:10:17: instantiated from here
/usr/lib/gcc/i486-slackware-linux/4.5.2/../../../../include/c++/4.5.2/bits/stl_algo.h:2211:4:
error: passing 'const Node >' as 'this'
argument of 'bool Node::operator<(const Node&) [with T =
std::basic_string]' discards qualifiers
I've highlighted the illuminating bits. This tells me that in OP's actual code, because of how the code is constructed (maybe the sort call is itself in a const member function? who knows...) the this pointer must be const, but as we can see from the posted declaration of operator<, the method is not const. The "qualifiers" referred to in the compiler errors are what the Standard calls "cv-qualifiers". "cv" stands for "const/volatile."
When the compiler says "Passing const X as this to Node::operator< discards qualifiers" what it's really trying to say is:
"You said X was const but then you tried to call a non-const member function through const X. In order for me to make this call, I would have to discard the const qualifier on X. I'm not allowed to do that, so you have to fix your code."
The qualifiers being "discarded" here are the qualifiers on the method itself. In other words, operator< must be a const member function, but it's not.
bool operator<(const Node<T>& rhs) const {
return size() < rhs.size();
}
Making the operator const as it should be may help with not angering the compiler.
Note: The problem arises because this is always const so the compiler expects you to promise not to change it which you specify by making the method using this to have the const qualifier.
Alternately you could make a non-member comparison for use with sort like so:
<template typename T>
struct CompareNodes {
bool operator()(const Node<T>& lhs, const Node<T>& rhs) const
{
return lhs.size() < rhs.size();
}
};
std::sort(path.cbegin(), path.cend(), CompareNodes<T>());