Const decltype (* std :: begin (container)) & val doesn't val const?

This piece of code:

std::vector <int> ints(5,1); std::for_each(ints.begin(), ints.end(), [](const decltype(*std::begin(ints))& val){ val*=2; }); 

compiles and works fine in Visual Studio 2010 and modifies each value in the container, as if the const keyword was not there. Is this a bug in the compiler since the expected behavior is that val is not modifiable? (in other words, I expect it to not compile, but it does)

Update:

 std::for_each(ints.begin(), ints.end(), [](const std::remove_reference<decltype(*std::begin(ints))>::type& val){ val*=2; }); 

It seems to behave correctly, but it does not make me smarter.

Note:

decltype(*std::begin(ints)) is a reference to int.

+4
source share
1 answer

It seems that the compiler is trying to apply const to int& , making it int& const , which is superfluous, since the link cannot be redone 1) Try to put a constant between decltype and the link: decltype(*ints.begin()) const&

1) Thanks for the comments.

Drop that thanks to @Ben's comment, I noticed a real problem. Try decltype(*ints.cbegin()) . cbegin returns a const_iterator , which is shared by a const-reference. In addition, there is no need for an extra ampersand, since *ints.cbegin() already returns int const& .

To explain what went wrong in the OP code, it just like @Ben Voigt says in the comments: decltype(*std::begin(ints)) resolves int& since std::begin(ints) returns a non-constant iterator for containers without constants and dereferencing, such an iterator returns a reference to non-const.

+8
source

Source: https://habr.com/ru/post/1381675/


All Articles