passing 'const QVariant' as 'this' argument discards qualifiers [-fpermissive] - c++

I have a struct like this:
struct StorageConfig {
QString id;
QString description;
QVariant value;
};
I want to assign the value of a QLineEdit to the value of my StorageConfig.value:
for (int j=0; j<parameters.count(); j++) {
if (parameters.at(j).id == id) {
parameters.at(j).value = QVariant(myQLineEdit->text());
break;
}
}
parameters is a QList<StorageConfig>
But I got this error:
passing 'const QVariant' as 'this' argument discards qualifiers [-fpermissive]
parameters.at(j).value = QVariant(myQLineEdit->text());
^
I understand perfectly the issue : myQLineEdit->text() return a const and I cannot assing a const to a non-const variable. That's OK.
But my problem is… I don't know how to solve this.
I can't remove const status of text() because it's an internal Qt method.
And I don't want to change my StorageConfig.value to const because I want to be able to modify it later.
I just want to get rid of this const on my QString. But I don't know how.
I've tried with std::remove_const and by storing text() in a temporary QString but it didn't work.
So, I'm out of ideas.
Any help?
Thanks.

The problem is that QList::at() returns const T &. Use QList::operator[] instead: parameters[j].value = QVariant(myQLineEdit->text());.

Related

Appending one QByteArray to another QByteArray

I wrote the following function, which is supposed to allow me to append some input QByteArray data to a private QByteArray inside of my class:
void addQByteArray(QByteArray* array)
{
p_commandArray.append(array);
}
My understanding is that the append function should also accept a QByteArray as a parameter, but I'm getting this error when I try to compile:
error: invalid conversion from ‘QByteArray*’ to ‘char’ [-fpermissive]
p_commandArray.append(array);
^
What am I doing wrong here?
Yes QByteArray::append has an overload that you can pass a QByteArray (more precicelsy a const QByteArray&), but what you attempt to pass is a pointer to QByteArray.
Either
void addQByteArray(QByteArray& array)
{
p_commandArray.append(array);
}
or
void addQByteArray(QByteArray* array)
{
p_commandArray.append(*array);
}
Prefer the first (passing a reference), because using pointers only makes sense when a nullptr is a valid parameter, but when you pass a nullptr you shall not dereference it.
The error message you get is due to another overload of append that takes a char as parameter.
QByteArray::append accepts const QByteArray&, but you give it a pointer. Give it an object:
void addQByteArray(QByteArray* array) {
p_commandArray.append(*array);
// ^ dereference
}

Problem when attempting to change the value of a two-dimensional vector

I am trying to change the values of a two-dimensional QVector (QVector<QVector<QString>). However when attempting it, I get the following error: passing 'const QString' as 'this' argument discards qualifiers [-fpermissive].
I first thought that the problem was in the way I was accessing the data in the QVector. I therefore tried accessing it via operator []. This gave me the following error: no match for 'operator=' (operand types are 'QVector<QString>' and 'QString'). I also tried dereferencing the vector (*SecondList), as I wasn't sure whether operator [] did it and got the following error: no match for 'operator*' (operand type is 'const QVector<QString>') .
Here is the problematic code:
void Handler::changePassword(QString newPassword, int id)
{
QString nP = newPassword;
int i = 0;
bool loopBreaker = false;
while (!loopBreaker)
{
if (SecondList->at(i).at(2) == QString::number(id))
{//Changes the value for password in "secondlist"
SecondList->at(i).at(0) = nP; // ----> ERROR
loopBreaker = true;
saveList();
}
i++;
}
}
Here is the header file for Handler class
class Handler : public QWidget
{
private:
QVector<QVector<QString>> *SecondList = new QVector<QVector<QString>>;
}
(code is ommitted for readability)
QVector at() returns a const T&, try using operator [] instead, which returns non-const &
So Ben answered this question over here
But the reason is that the QVector::at method is const and the full prototype is const T &QVector::at(int i) const.
So you are going to have to use the QVector::operator[] which the full prototype is T &QVector::operator[](int i)
So I would try SecondList->operator[](i).operator[](0) = nP;. Something along these lines.

c++ QVector/Vector issues... const... discards qualifiers

I setup a class called tagToken.
It has setter functions, one is void setString(QString)
I have it defined/declared as such
.h file
void setString(QString string);
Private:
QString stringOfTagToken ;
.cpp file
void tagToken::setString(QString string)
{
stringOfTagToken = string;
}
When I try to run this code:
if (linePosition == 1)
{
QVector<tagToken> temp(0);
//errors
//temp.at(0).setString(line);
temp.at(0).setString("test");
//tags.at(0).setString(line);
//tags.push_back();
tagTokenCounter++;
}
I get this error:
C:\Dev\DiffMatchPatch\diffmatchpatch.cpp:316: error: passing 'const tagToken' as 'this' argument of 'void tagToken::setString(QString)' discards qualifiers [-fpermissive]
temp.at(0).setString("test");
QVector's at function returns data as const. Use at when you don't want to (accidentally) change the vector data, or operator[] in general.
temp[0].setString("test");
QVector::at() returns a const ref to your data, you cannot call a non-const method like setString on that
From http://qt-project.org/doc/qt-4.8/qvector.html#at
const T & QVector::at ( int i ) const
Returns the item at index position i in the vector.
i must be a valid index position in the vector (i.e., 0 <= i < size()).
Consider using operator[] instead

stl map const_iterator and g++ error

I'm trying to port some windows"s MFC class to linux because I have to port a windows software to linux.
here is the code I need to port
165: SMapCI it = _s$.find("nchairs");
166: if (it==_s$.end()) return 10;
167: int n = strtoul(it->second.text.GetString(), NULL, 10);
and _s$ and SMapCI are defined like this
typedef std::map<CString, STablemapSymbol> SMap;
SMap _s$;
typedef SMap::const_iterator SMapCI;
So, here is my CString class
class CString {
protected:
std::string str;
public:
CString(const char *_cstr) { str = _cstr;; };
bool operator<(char *_cstr) const { return str < _cstr;};
const char *GetString() { return str.c_str();};
};
And When I build my code, I get following error:
CTablemap/CTablemap.h:167:54: error: passing ‘const CString’ as ‘this’ argument of ‘const char* const CString::GetString()’ discards qualifiers [-fpermissive]
I don't understand this error.
g++ documentation say that
passing 'const OBJECT' as 'this' argument of 'FUNCTION' discards qualifiers
*Message found in GCC version 4.5.1
*you're returning an address
*you're attempting to access a container element with a const_iterator using a member function that has no non-const versions. The non-const function does not guarantee it will not alter the data
but ... my GetString function is defined as "const char *", so I have the keyword const ...
So I don't get it ... any help will be more than welcome
note: I'm using my own CString class instead of directly changing it with std::string because the code I want to port is too huge, and I want to do the minimum modification on it. (and some function defined in CString are not defined in std::string)
thanks in advance for any help !!
Your function signature should be
const char *GetString() const
Notice the last const.
Right now, you're saying, "I'm returning a const char pointer from a non-const CString instance". This is fine, but what you're being asked to do is define a function that can be used on a const CString instance - and that's what the last const (after the function parameter list) does, specify that that function can be called on a const CString.
You may want both versions of that function, but in particular, you need it here because the const_iterator exposes its contents as const objects, regardless of what they are inside the container itself.
The prototype of GetString should be:
const char *GetString() const;
The first const means that the caller cannot modify the returned value. The second const means that this method can be called for a const CString.
On the other hand, I would also change the operator< and use:
bool operator<(const char *_cstr)

passing ‘const Link’ as ‘this’ argument of ‘std::string GetAttribute(std::string)’ discards qualifiers

I'm getting an odd error with parts of the NS-3 API. Here is my error message:
error: passing ‘const ns3::TopologyReader::Link’ as ‘this’ argument of ‘std::string ns3::TopologyReader::Link::GetAttribute(std::string)’ discards qualifiers
And here is the code causing the issue:
TopologyReader::ConstLinksIterator iter;
int num = 0;
for (iter = topologyReader->LinksBegin (); iter != topologyReader->LinksEnd(); iter++, num++)
{
std::istringstream fromName(iter->GetFromNodeName ());
std::istringstream toName (iter->GetToNodeName ());
iter->GetToNodeName();
std::string w = "Weight";
std::string weightAttr = (iter)->GetAttribute(w); // <- error
/* snip */
}
I think it might have to do with the fact that GetAttribute(std::string) is not a const function, according to the documentation for TopologyReader::Link, while the other functions, GetFromNodeName(void) and GetToNodeName(void) are declared as const functions. However, I'm not sure how to fix this problem.
Edit:
The function signatures are as shown (from the linked documentation):
std::string ns3::TopologyReader::Link::GetFromNodeName (void) const
std::string ns3::TopologyReader::Link::GetToNodeName (void) const
std::string ns3::TopologyReader::Link::GetAttribute (std::string name)
Your analysis is correct. The obvious fix is to make GetAttribute be a const function. Its name suggests it should be const. It might not be in your power to change that code, though.
The alternative is to find some way of getting a non-const object to call the function on. Maybe you could declare iter as a LinksIterator instead of a ConstLinksIterator.
As a last resort, you could try using const_cast to tell the compiler that it's really safe to call a non-const method on a supposedly const object.