1

I am trying to delete a cookie but am getting the error:

error C2440: 'initializing' : cannot convert from 'const QNetworkCookie' to 'QNetworkCookie &'

I am confused why the compiler is complaining about const QNetworkCookie (I am assuming it is complaining about my foreach()).

void PersistentCookieJar::deleteCookie(const QString cookieName) {
    QList<QNetworkCookie> cookies = allCookies();
    foreach(QNetworkCookie &cookie, allCookies()) {
        if (cookie.name() == cookieName) {
            cookie.setValue(""); // delete the cookie
            break;
        }
    }
}
Jon
  • 8,205
  • 25
  • 87
  • 146

2 Answers2

0
void PersistentCookieJar::deleteCookie(const QString cookieName) {
    QList<QNetworkCookie> cookies = allCookies();
    foreach(QNetworkCookie &cookie, cookies) {
        if (cookie.name() == cookieName) {
            cookie.setValue(""); // delete the cookie
            break;
        }
    }
    setAllCookies(cookies);
}
WAFFO
  • 60
  • 9
  • `QList QNetworkCookieJar::allCookies() const`. So compiler is complaining because allCookes() is returning a const? How would I change how `allCookies()` returns my `QList`? – Jon Jun 17 '17 at 00:07
  • Yeah I'm guessing it only wants you to work with setters and getters. So you need to copy the whole list, edit the list, then set the cookies to your new list. Going to edit my answer above. – WAFFO Jun 17 '17 at 00:59
0

There is a basic difference between Qt's range for (Q_FOREACH, foreach) and its C++11's homonymous: you cannot use Qt's one for modifying the elements of a container.

The reason is that Qt's implementation returns a constant reference for each element, while C++11 can work with non-const references. In your case, you are trying to initialize a reference from a constant (the one that Q_FOREACH returns), so you get a compilation error. As you see, it has nothing to do with the constness of the allCookies() method.

If instead of the Q_FOREACH you directly use iterators or indices to iterate your container, then you are accessing the actual elements so you can modify them.

This code snippet illustrates some possible ways (wrong and correct) to iterate using Q_FOREACH (exhaustive iterator versions obviated for simplicity):

QList<QString> stringlist; // applies to any element type
stringlist.append("foo");

// 1, compiles but doesn't modify the list since 's' is a copy
foreach (QString s, stringlist) {
  s += "bar";
}
qDebug() << stringlist;

// 2, doesn't compile ('s' is constant and cannot be modified)
/*foreach (const QString& s, stringlist) {
  s += "bar";
}*/

// 3, equivalent to 1, compiles but doesn't modify the list
foreach (auto s, stringlist) {
  s += "bar";
}
qDebug() << stringlist;

// 4 (your case), doesn't compile, 's' cannot be initialized from a constant
/*foreach (QString& s, stringlist) {
  s += "bar";
}*/

// 5, using indices
for (int ii = 0; ii < stringlist.count(); ++ii) {
  stringlist[ii] += "bar";
}
qDebug() << stringlist;

// 6, using iterators
for (auto it = stringlist.begin(); it != stringlist.end(); ++it) {
  *it += "bar";
}
qDebug() << stringlist;

You can check this question for more info about how the Q_FOREACH macro works.

cbuchart
  • 10,847
  • 9
  • 53
  • 93