C++ Discard qualifiers on iterator (const) - c++

I got a problem with a iterator. When i compile my project i keep getting this error.
Kitchen.cpp: In member function ‘void Kitchen::If_Cook_Ok(const Order&) const’:
Kitchen.cpp:45:33: error: passing ‘const Order’ as ‘this’ argument of ‘std::list<IngredType::Ingredient> Order::getIngredient()’ discards qualifiers [-fpermissive]
Kitchen.cpp:45:70: error: passing ‘const Order’ as ‘this’ argument of ‘std::list<IngredType::Ingredient> Order::getIngredient()’ discards qualifiers [-fpermissive]
I already tried to put constness on the function member, but i keep getting this error. Here is the code
The Order class has as member variable a std::list witch is returned by the getter getIngredients()
void Kitchen::If_Cook_Ok(const Order &order) const
{
std::cout << "congratulations you barely made it" << std::endl;
std::list<IngredType::Ingredient>::const_iterator it;
for (it = order.getIngredient().begin(); it != order.getIngredient().end(); ++it)
{
std::cout << *it << std::endl;
}
}
Help will be much appreciated.

order is a const Order&. Thus, you could only call const methods of Order class. And it appears that Order::getIngredient() is not const.

TheOrder parameter in the method If_Cook_Ok is const, so you can only call const methods on this object. Perhaps the getIngredients() method is not const. Try adding const on that method.

Related

How does member-function understand that the object is obtained by dereferencing a const pointer?

I created a const pointer which points to an instance of abject allocated dynamically.I could not understand the object itself is const or not.
Firstly I tried to call a non-const member function by using pointer, as expected it caused a compile error because (it is my explanation, don't know if it is true or not) this pointer created by the member function is assigned to that const pointer. It did not yield anything.
Secondly I tried to dereference the pointer and call that non-const member function. I thought that the this pointer created by member function now will not be a const pointer because compile can not know the object returned by p (namely *p) is returned by a const pointer or not. It turns out that I was mistaken.
How does member-function understand that ?
#include<iostream>
class A
{
int a=4;
public:
A()
{}
void print()
{
std::cout<<a<<std::endl;
}
};
int main()
{
const A* p = new A();
p->print(); //1 causes compile error
(*p).print(); //2 causes compile error
return 0;
}
I thought the line labelled as 2 will not create a compile error.
It causes a compile error.The error message is:
"a.cpp: In function ‘int main()’:
a.cpp:21:13: error: passing ‘const A’ as ‘this’ argument discards qualifiers [-fpermissive]
p->print(); //1 causes compile error
^
a.cpp:10:9: note: in call to ‘void A::print()’
void print()
^~~~~
a.cpp:22:15: error: passing ‘const A’ as ‘this’ argument discards qualifiers [-fpermissive]
(*p).print(); //2 causes compile error
^
a.cpp:10:9: note: in call to ‘void A::print()’
void print()
^~~~~
Variables have types and can therefore be const or non-const, but expressions have types too. The type of (*p) is const A, and you can't call a non-const method of a const type.
There is no difference between (1) and (2). (1) is syntax sugar for (2).
You should define the print method as const in order to call it for const object.
void print() const { ... }
As it has already been noted, expressions have types and the type of (*p) is const A. You cannot call a non-const function on an object of a const type but you can call const member function. Member functions can have a const qualifier which will mark them to be able to be invoked on const objects or pointers to const objects.
void print() const
{
std::cout<<a<<std::endl;
}
This will make your code compile. and it looks like this is what you intended to do anyway.

Using std::sort on a vector of objects doesn't work on compiler

I am trying to sort a vector of objects. I have written a function to compare the objects. It seems to work fine on my compiler but not the one my school's server has.
bool sortByLastName(Student& lhs, Student& rhs) {
string lhsLastName = lhs.getLastName();
string rhsLastName = rhs.getLastName();
return lhsLastName < rhsLastName;
}
I get this error...
/usr/lib/gcc/i686-redhat-linux/4.4.7/../../../../include/c++/4.4.7/bits/stl_algo.h:131: error: invalid initialization of reference of type ‘Student&’ from expression of type ‘const Student’
/usr/lib/gcc/i686-redhat-linux/4.4.7/../../../../include/c++/4.4.7/bits/stl_algo.h:133: error: invalid initialization of reference of type ‘Student&’ from expression of type ‘const Student’
I tried to make the arguments const String& but that also resulted in this error...
Lab9Roster.cpp:79: error: passing ‘const Student’ as ‘this’ argument of ‘std::string Student::getLastName()’ discards qualifiers
Lab9Roster.cpp:80: error: passing ‘const Student’ as ‘this’ argument of ‘std::string Student::getLastName()’ discards qualifiers
Define getLastName as
string getLastName() const;
and return
return lhs.getLastName() < rhs.getLastName();
I am sure you are passing temporary parameters like sortByLastName("s1", "s2"). However, though I doubt if it would work on some compilers, mostly non-const references don't bind to temporary objects.
Use
bool sortByLastName(const Student& lhs,const Student& rhs) {
string lhsLastName = lhs.getLastName();
string rhsLastName = rhs.getLastName();
return lhsLastName < rhsLastName;
}
Also, as #user3435400 has mentioned, define getLastName() as const, that is it cannot modify any class members
string getLastName() const;

error: passing ‘const ...'’ as ‘this’ argument of ‘...’ discards qualifiers [duplicate]

This question already has answers here:
c++ passing a const object reference to a function
(5 answers)
Closed 9 years ago.
stockListType.cpp:58: instantiated from here
/usr/include/c++/4.2.1/bits/stl_algo.h:91: error: passing ‘const stockType’ as ‘this’ argument of ‘bool stockType::operator<(const stockType&)’ discards qualifiers
/usr/include/c++/4.2.1/bits/stl_algo.h:92: error: passing ‘const stockType’ as ‘this’ argument of ‘bool stockType::operator<(const stockType&)’ discards qualifiers
/usr/include/c++/4.2.1/bits/stl_algo.h:94: error: passing ‘const stockType’ as ‘this’ argument of ‘bool stockType::operator<(const stockType&)’ discards qualifiers
/usr/include/c++/4.2.1/bits/stl_algo.h:98: error: passing ‘const stockType’ as ‘this’ argument of ‘bool stockType::operator<(const stockType&)’ discards qualifiers
/usr/include/c++/4.2.1/bits/stl_algo.h:100: error: passing ‘const stockType’ as ‘this’ argument of ‘bool stockType::operator<(const stockType&)’ discards qualifiers
Above is the error I got and would like someone to explain to me what it means. I solved the error by placing a constant in front of the overloading operator. My program was a stock market application that read a file that includes a string, 5 doubles and an int. We sort out the program by the string symbols and the index gain. The book instructed me to use vectors to store each data. As you see below the overload operator compares each symbol and sorts it out using the sort member function of containers. My question is why did I have to put a constant in front of the overload operator for > and <. but not for >=, <=, ==, != overload operators.
//function was declared in stockType.h and implemented in stockType.cpp
bool operator<(const stockType& stock)//symbol is a string
{
return (symbols < stock.symbols)
}
//The function below was defined in stockListType.h and implemented in
// stockListType.cpp where I instantiated the object of stockType as a vector.
//vector<stockType> list; was defined in stockListType.h file
void insert(const& stockType item)
{
list.push_back(item);
}
void stockListType::sortStockSymbols()
{
sort(list.begin(), list.end());
}
The error message tells you that you that you are casting of const from your object in operator< function. You should add const to all member functions that don't modify member.
bool operator<(const stockType& stock) const
// ^^^^^
{
return (symbols < stock.symbols)
}
The reason why compiler complains about operator< is because std::sort uses operator< to compare the elements.
Also you have another syntax error in insert function.
Update:
void insert(const& stockType item);
to:
void insert(const stockType& item);
// ^^

trouble creating a custom sort in C++ for a vector of pointers

I am trying to create a custom sort for a vector of class pointers by using a sort predicate:
struct sort_by_airtime
{
inline bool operator() (const Network *n1, const Network *n2)
{
return (n1->airtime() < n2->airtime());
}
};
For each network, we sort by a float returned by airtime().
Now, I try to use this as follows:
std::vector<Network *> Simulator::sort_networks(std::vector<Network *> netlist, bool sort_airtime) {
std::vector<Network *> new_netlist = netlist;
if(sort_airtime) {
sort(new_netlist.begin(), new_netlist.end(), sort_by_airtime());
}
}
However, I get a lot of errors like this:
In file included from Simulator.cpp:7:
Simulator.h: In member function ‘bool Simulator::sort_by_airtime::operator()(const Network*, const Network*)’:
Simulator.h:48: error: passing ‘const Network’ as ‘this’ argument of ‘virtual float Network::airtime()’ discards qualifiers
Simulator.h:48: error: passing ‘const Network’ as ‘this’ argument of ‘virtual float Network::airtime()’ discards qualifiers
Am I not specifying the argument passed to the predicate properly? airtime() is implemented by classes that inherit the Network class.
The compiler is warning you that Network::airtime() is ignoring the const qualifiers on n1 and n2.
The solution would be to create a "const-correct" version of Network::airtime() (assuming it actually doesn't modify anything).
See this answer for an example.
Your member function should be declared as const member function as:
virtual float Network::airtime() const
^^^^^ //this makes the function const
because the pointers which you're using in operator() are pointing to const objects of type Network.
Network::airtime() is not const, and so can't be called via the const Network* you have in sort_by_airtime.
If possible, the best solution is to make airtime() const; otherwise change the sort_by_airtime arguments to Network*.

Discards qualifiers error

For my compsci class, I am implementing a Stack template class, but have run into an odd error:
Stack.h: In member function ‘const T Stack<T>::top() const [with T = int]’:
Stack.cpp:10: error: passing ‘const Stack<int>’ as ‘this’ argument of ‘void Stack<T>::checkElements() [with T = int]’ discards qualifiers
Stack<T>::top() looks like this:
const T top() const {
checkElements();
return (const T)(first_->data);
}
Stack<T>::checkElements() looks like this:
void checkElements() {
if (first_==NULL || size_==0)
throw range_error("There are no elements in the stack.");
}
The stack uses linked nodes for storage, so first_ is a pointer to the first node.
Why am I getting this error?
Your checkElements() function is not marked as const so you can't call it on const qualified objects.
top(), however is const qualified so in top(), this is a pointer to a const Stack (even if the Stack instance on which top() was called happens to be non-const), so you can't call checkElements() which always requires a non-const instance.
You cannot call a non-const method from a const method. That would 'discard' the const qualifier.
Basically it means that if it allowed you to call the method, then it could change the object, and that would break the promise of not modifying the object that the const at the end of the method signature offers.
You're calling a non-const method from a const method.
Because checkElements() isn't declared const.
void checkElements() const {
if (first_==NULL || size_==0)
throw range_error("There are no elements in the stack.");
}
Without that declaration, checkElements cannot be called on a const object.