2

I'm getting into C++11 and really can't understand why this happens:

const int arrSource[4] = { 5,7,6,4 };
for (auto& i : arrSource) {
    std::cout << i << " ";
    ++i; //error
}

It says that i must be a modifiable lvalue and i: you cannot assign to a variable that is const.

So it means, that if the arrSource[] is const, it makes i const too?

Niall
  • 30,036
  • 10
  • 99
  • 142
  • Replace `auto&` with `auto`. – Mohamad Elghawi Feb 11 '16 at 11:20
  • @MohamadElghawi I know this, but thank you! Just couldn't get why it doesn't work with reference. –  Feb 11 '16 at 11:28
  • 1
    Have a look at [this](http://stackoverflow.com/questions/7138588/c11-auto-what-if-it-gets-a-constant-reference) answer. It explains that `auto&` retains the constness of whatever it refers to and `auto` does not. That is why removing the `&` works. – Mohamad Elghawi Feb 11 '16 at 11:34
  • 1
    @JuliaStefanyshyna If you remove the reference you are actually creating and using a new object via copy-initialization. Which is of course allowed to be modified as it's not const. – Simon Kraemer Feb 11 '16 at 11:35
  • 2
    Or to make it short: You can't have a non-const reference to an object that is const itself in the same context. – Simon Kraemer Feb 11 '16 at 11:36
  • @MohamadElghawi shame, that I didn't see this answer before. Thanks for your help! –  Feb 11 '16 at 11:48

2 Answers2

5

So it means, that if the arrSource[] is const, it makes i const too?

Yes, if the array is const, each element in the array is also const.

The auto& deduces the type based on the initialiser, in this case it is deduced to be int const& and hence cannot be modified.

The increment is probably not needed (not sure on your intent). The range based for loop takes care of the incrementing between iterations.

If modification of the array is intended (via i), then you need to remove the const.

Niall
  • 30,036
  • 10
  • 99
  • 142
2

N4567 § 3.9.3 [basic.type.qualifier] p6

Cv-qualifiers applied to an array type attach to the underlying element type, so the notation “cv T”, where T is an array type, refers to an array whose elements are so-qualified. An array type whose elements are cv-qualified is also considered to have the same cv-qualifications as its elements.

cpplearner
  • 13,776
  • 2
  • 47
  • 72