Nyaruko
Nyaruko

Reputation: 4489

Why necessary to make copy first when using iterator on implicitly shared container?

The Qt's documentation says the following:

Thanks to implicit sharing, it is very inexpensive for a function to return a container per value. The Qt API contains dozens of functions that return a QList or QStringList per value (e.g., QSplitter::sizes()). If you want to iterate over these using an STL iterator, you should always take a copy of the container and iterate over the copy. For example:

// RIGHT
const QList<int> sizes = splitter->sizes();
QList<int>::const_iterator i;
for (i = sizes.begin(); i != sizes.end(); ++i)
    ...

// WRONG
QList<int>::const_iterator i;
for (i = splitter->sizes().begin();
        i != splitter->sizes().end(); ++i)
    ...

What will happen if the 'Wrong' method is applied?

Upvotes: 9

Views: 335

Answers (1)

Igor Tandetnik
Igor Tandetnik

Reputation: 52571

The two calls to splitter->sizes() produce two distinct copies of the container. Since begin() comes from one and end() from the other, they don't form a valid range. The loop would then walk off the end of the first container, into the land of undefined behavior.

Range-based loop would work just fine though: for (int size: splitter->sizes()) { ... }

Upvotes: 12

Related Questions