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

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

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.

Intel TBB, exececute a member function with a parallel for

I have a class similar to this one:
struct orden
{
long long time;
double price;
const char* time1;
orden(const char* t, double p) : time1(t),price(p){};
void convertToMs()
{
time = dateToMs2(time1);
}
};
The what I'm doing is to read a file in serial, execute the constuctor of the struct and save the generated object in a vector of orden:
vector<orden> ord;
ifstream fe(filename)
while(getline(fe,order_line))
{
price = stod(order_line.substr(position+2));
time = order_line.substr(0,26).c_str();
ord.push_back(time, price);
}
Then, what I want to do in parallel is to execute the member function convertToMs(). But I have problems because the compiler ask me to execut only constant functions inside parallel for.
I have tryed some thinks that I have found like this one Without sucess because they are not saving the result of the execution in a parameter of the object.
What I'm doing wrong?
Thank you in advance
EDIT:
If I use
struct orden
{
long long time;
double price;
const char* time1;
orden(const char* t, double p) : time1(t),price(p){};
void convertToMs() const
{
time = dateToMs2(time1);
}
};
I have the following error:
In file included from pract1.cpp:5:0:
orden.h: In member function ‘void orden::convertToMs() const’:
orden.h:29:27: error: assignment of member ‘orden::time’ in read-only object
time = dateToMs2(time1);
If I delete the const i have the following one:
pract1.cpp: In lambda function:
pract1.cpp:158:43: error: passing ‘const value_type {aka const orden}’ as ‘this’ argument discards qualifiers [-fpermissive]
ordersOfTheCompany[j].convertToMs();
^
In file included from pract1.cpp:5:0:
orden.h:27:8: note: in call to ‘void orden::convertToMs()’
void convertToMs()
EDIT 2:
Sorry again, i have the folloging code:
vector<orden> ord;
while(getline(fe,order_line))
{
price = stod(order_line.substr(position+2));
time = order_line.substr(0,26).c_str();
ord.push_back(time, price);
}
tbb::parallel_for(tbb::blocked_range<size_t>(0,ord.size()),
[=](tbb::blocked_range<size_t>& r) {
for(std::size_t j=r.begin(); j!=r.end(); ++j)
{
ord[j].convertToMs();
}});
I'm trying to execute the member function in a parallel for
The documentation for parallel_for has an example similar to what you're trying to do. It saves the result into a separate array from the input array.
In your case, you'd want to add something like
std::vector<long long> outTime;
outTime.resize(ord.size());
right before the parallel_for call. Then, in the body of the lambda you execute, change the statement to
outTime[j] = ord[j].convertToMs();
after changing convertToMs to be a const function that returns the converted value rather than saving it locally. After the parallel_for returns, copy the results out of outTime back into ord.
You could have 2 versions of convertToMs, a non-const one that saves the result internally, and a const one that returns the converted time.

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

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());.

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)