C++ const decltype(*std::begin(container))&;瓦尔没有';你不能让瓦尔康斯特吗?

C++ const decltype(*std::begin(container))&;瓦尔没有';你不能让瓦尔康斯特吗?,c++,visual-c++,lambda,constants,c++11,C++,Visual C++,Lambda,Constants,C++11,这段代码: std::vector <int> ints(5,1); std::for_each(ints.begin(), ints.end(), [](const decltype(*std::begin(ints))& val){ val*=2; }); std::vector ints(5,1); std::for_each(ints.begin()、ints.end()、[](const decltype(*std::begin(ints))&val){val*=

这段代码:

std::vector <int> ints(5,1);
std::for_each(ints.begin(), ints.end(), [](const decltype(*std::begin(ints))& val){ val*=2; });
std::vector ints(5,1);
std::for_each(ints.begin()、ints.end()、[](const decltype(*std::begin(ints))&val){val*=2;});
在VisualStudio2010中编译并运行良好,并修改容器中的每个值,就像不存在const关键字一样。这是否是编译器中的一个bug,因为预期的行为是val是不可修改的?(换句话说,我希望它不会编译,但它会编译)

更新:

std::for_each(ints.begin()、ints.end()、[](const std::remove_reference::type&val){val*=2;});
看起来行为正常,但这并不能让我更聪明

注:

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

编译器似乎试图将
常量应用于
int&
,使其成为
int&const
,这是多余的,因为引用无论如何都无法重置1)。尝试将常量放在
decltype
和引用之间:
decltype(*ints.begin())常量&

1) 谢谢你的澄清意见

废话,感谢@Ben的评论,我注意到了真正的问题。尝试
decltype(*ints.cbegin())
cbegin
返回一个
const\u迭代器
,该迭代器取消对const的引用。另外,由于
*ints.cbegin()
已经返回了一个
int常量&
,因此不需要额外的和


为了解释OP代码中的错误,正如@Ben Voigt在评论中所说:
decltype(*std::begin(ints))
解析为
int&
,因为
std::begin(ints)
返回非常量容器的非常量迭代器,取消引用此类迭代器将返回对非常量的引用。

gcc只是拒绝编译:
错误:“const”限定符不能应用于“int&”
。它拒绝编译两个版本?当然,第二个不编译,因为
val
是一个常量,不能是
*=2
-ed。啊,是的,愚蠢的我=)这就是它应该做的,但是第一个在gcc中也不编译?@BenVoigt:是的,如果引用是通过
typedef
或模板参数(§8.3.2/1)引入的,那么
常量将被忽略. 
decltype
不是其中之一。GCC应该忽略常量,使生成的类型成为
int&
@Johannes:为什么?我希望代码会给我一个编译错误。将
const
应用于
int&
是完全合法的:(Comeau也接受它)。@Ben:有趣的是,我会相应地修改我的答案。不过,仅仅因为有两个编译器接受它并不意味着它本身就是合法的。不过我还是相信你和约翰。@Xeo:你的解决办法没用。
declspec
部分解析为
int&
,已经是一个参考。
std::for_each(ints.begin(), ints.end(), [](const std::remove_reference<decltype(*std::begin(ints))>::type& val){ val*=2; });