Learning about std::as_const, Qt containers and that detach might not mean what you think

published at 19.06.2025 17:32 by Jens Weller
Save to Instapaper Pocket

Recently I've copied and refactored code that handles the import of attendees for Meeting C++ 2025 from Tito and EventBrite by getting a JSON Document from a web API...

....and without doing much I've noticed a clazy warning: "c++11 range-loop might detach Qt container (QJsonArray) [clazy-range-loop-detach]".

The code triggering this warning is classic for when I do import handling from JSON:

for(const auto& reg:registrations)

The fix for this is using std::as_const or qAsConst on the container. So a simlpe std::as_const(registrations) fixes this, also one could declare the container const, as the code shouldn't change it anyways. But this code started its life time well over 10 years ago when it handled the import for Xing Events, which held as a service for 10 years. Only in 2023, I had to start looking for a replacement, but thats a different story.

Back to C++, the error message says Qt Container might detach something something... Sounds not so bad right?

To be honest, in my case it does not matter much, but as a dev I wanted to know what detach really means. I know std::thread has a detach function, otherwise I'm not sure if detach was used in boost smart pointers, the modern interface in unique_ptr uses release. Though in the context of Qt and the code above all this becomes a bit odd. 

You can find the long and detailed explanation in KDABs blog. Qt likes copy and write, and I already had the hunch that this could be in play here. Oddly at first I've thought that this may invoke moving that container into the loop. But the code actually could trigger a copy of the container, which than is temporary for the scope of the loop. 

And making the container const or turning it into a const reference via std::as_const prevents Qt to kick in its copy on write mechanisms, as now everything in play is const. It also gets you rid of the warning in Qt Creator.

I've decided to go with the std::as_const fix sofar:

for(const auto& reg:std::as_const(registrations))

...but writing this blog entry has got me thinking if the const container is not the better approach.

Join the Meeting C++ patreon community!
This and other posts on Meeting C++ are enabled by my supporters on patreon!