const decltype(*std::begin(container))& val dont make val const?

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

本文关键字:const val dont make begin decltype std container      更新时间:2023-10-16

这段代码:

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

在Visual Studio 2010中编译和运行得很好,并且可以修改容器中的每个值,就像没有const关键字一样。这是编译器中的一个错误,因为预期的行为是val是不可修改的?(换句话说,我希望它不能编译,但它确实编译了)

更新:

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

的行为似乎是正确的,但这并没有使我更聪明。

注意:

decltype(*std::begin(ints))是对int类型的引用。

似乎编译器试图将const应用于int&,使其成为int& const,这是多余的,因为引用无论如何都不能重新定位1)。试着把const放在decltype和引用之间:decltype(*ints.begin()) const&

放弃,感谢@Ben的评论,我注意到了真正的问题。试试decltype(*ints.cbegin())cbegin返回const_iterator,它解引用到const的引用。此外,不需要额外的&号,因为*ints.cbegin()已经返回int const&

为了解释OP代码中的错误,就像@Ben Voigt在评论中所说的那样:decltype(*std::begin(ints))解析为int&,因为std::begin(ints)返回非const容器的非const迭代器,并且解引用这样的迭代器返回对非const的引用。