I have the following variable in QT:
QVector<QVector <int> > buff_d1;
and I need to modify the "inner" vector:
buff_d1.at(i).removeFirst();
buff_d1.at(i).push_back(d1.at(i).at(sample_number));
this is causing the errors:
passing 'const QVector<int>' as 'this' argument of 'void QVector<T>::removeFirst() [with T = int]' discards qualifiers [-fpermissive] buff_d2.at(i).removeFirst();
passing 'const QVector<int>' as 'this' argument of 'void QVector<T>::push_back(const T&) [with T = int]' discards qualifiers [-fpermissive] buff_d1.at(i).push_back(d1.at(i).at(sample_number));
I understand that the "inner" vector is const so I can't modify it, but what is the work around it?
Your at() function returns a const reference:
const T & QVector::at(int i) const
and you're trying to modify this with the removeFirst() function. You should rather use the [] operator to modify it since it provides a non-const returning overload:
T & QVector::operator[](int i)
The same applies for the second error.
at(int index) member function returns an const reference, see the documentation here, so you need to use operator[int index] to return a non const reference to be able to modify it.
Related
I have a member variable std::set<T*> m_associates;, i.e., a collection of non-const raw pointers, and simply want to check for existence of another pointer.
To maintain const correctness my function looks like this:
bool MyClass::is_associated(const T* x) const
{
return (m_associates.find(x) != m_associates.end());
}
However, this does not compile, since x is passed as const T* to indicate that the value pointed to by x is not changed by the function, but m_associates contains non-const T*.
If I remove const from the x parameter, it compiles, but violates const correctness...
Adding const to m_associates, i.e., std::set<const T*> m_associates; is not an option either as I need the non-const pointers elsewhere in my class.
How do I solve this? Is this (possibly the only) point where a const_cast should be used? Or do I have to always pass all parameter T pointers as non-const?
Edit:
Full error output, compiler is clang++-8, code is in C++17
error: no matching member function for call to 'find'
return (m_associates.find(x) != m_associates.end());
~~~~~~~~~~~~^~~~
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_set.h:798:7: note: candidate function not viable: 1st argument ('const T *') would lose const qualifier
find(const key_type& __x) const
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_set.h:804:2: note: candidate function template not viable: 'this' argument has type 'const std::set<T *>', but method is not marked const
find(const _Kt& __x)
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_set.h:794:7: note: candidate function not viable: 'this' argument has type 'const std::set<T *>', but method is not marked const
find(const key_type& __x)
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_set.h:810:2: note: candidate template ignored: substitution failure [with _Kt = const T *]: no matching member function for call to '_M_find_tr'
find(const _Kt& __x) const
^
The reason your current code fails is that the default Compare for std::set<T> is std::less<T>; which forces both arguments to be a T for comparison -- in this case, non-const T* types. Since const T* cannot be converted to T* without casting away the constness, this is causing your compile errors.
If you are using C++14 or above, you can redefine your std::set so that the Compare template type is a transparent comparator (one that deduces the underlying types for comparison), for example std::set<T*, std::less<>>. This will enable the overload of std::set::find that deduces the type and forwards the argument to the comparator, which will enable the above code to work.
You can cast away the const-ness of x with no ill-effects in this case.
Other than perhaps signalling a design flaw, the only thing you need to watch out with casting away const is that the behaviour on attempting to modify an object that was originally declared using const via the non-const pointer is undefined. That's not the case here.
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.
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);
// ^^
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*.
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.