isocpp / isocpp/CppCoreGuidelines
Guideline for how to declare variables in a range-based for loop
Nobody has claimed this yet.
- Dominant language
- CSS
- Stars
- 45.3k
- Forks
- 5.6k
- PR merge metrics
- No merged PRs in 30d
Description
A question which comes up every now and then is what type of loop variable you should use for range-based for, particularly when no mutation takes place.
// case (1) - cheap to copy
for (int x : container) // disallowed in this form by Con.1, should be 'const int'
// vs
for (const int &x : container)
// case (2) - expensive to copy
for (string x : container) // disallowed in this form by ES.71, should be 'const string &x'
// vs
for (const string &x : container)
I think we should recommend to always declare the loop variable as a reference, never as a value, and here's why:
- The rule is simple and consistent.
- When mutating a
T&variable in the loop, you are already forced to follow it by the language. - If you aren't, and you have case (2), then ES.71 already tells you to.
- Otherwise, if you are following Con.1, then
const T xis only one character away fromconst T &x, so it costs very little effort to follow this rule. - It is possible and relatively easy to enforce with automatic tooling.
- It prevents bugs related to taking the address of the local variable, instead of taking the address of the object within the container.
- Even for weird iterators like
std::ranges::iota_view::iterator, where theirreferenceis actually a value, this method is robust becauseconst&allows for temporary materialization.
In essence, I don't see any benefit to non-reference loop variables, and the alternative is consistent, easy, correct by default, and already recommended in part.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reviewing the existing Con.1 and ES.71 guidance and the five comments on this issue. Determine whether the proposed rule should replace or clarify those recommendations, including the cited range-based-for cases. Done means reaching a decision and documenting the agreed guidance in the relevant C++ Core Guidelines section.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- documentation
- Issue type
- Documentation
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 25/100