std::vector<const int> vci;
vci.push_back(1);
vci[0] = 2;
对于元素类型是const int
,赋值语句不应该分配给const int&
?这不会与LLVM 3.0一起编译。为什么VC++允许它?为什么VC++ 2010允许它编译?
std::vector<const int> vci;
vci.push_back(1);
vci[0] = 2;
对于元素类型是const int
,赋值语句不应该分配给const int&
?这不会与LLVM 3.0一起编译。为什么VC++允许它?为什么VC++ 2010允许它编译?
虽然它是未定义的行为,基本上什么可以发生,包括你所看到的,我已经跟踪到这似乎是与图书馆与标准不兼容。特别是VS2010库中定义的标准分配器不符合标准。
标准规定std::vector<T,Allocator>::value_type
是Allocator::value_type
的类型定义。现在默认分配器(如果没有提供)是std::allocator<T>
,其中value_type
,根据表28必须是与T相同。现在,VS2010中的标准分配器的实现将const
限定符从类型自变量中删除,因此std::allocator<const T>::value_type
为T
,而不是const T
。
重要的是要注意,由于它是未定义的行为并且编译器可以随心所欲地执行,因此编译器并不接受您提供的代码,因为它是不符合要求的。但另一方面,在std::allocator
实现中存在不符合。
您已经自行回答了问题:它是
未定义的行为。编译器不需要提供诊断,操作的结果可以是任何东西。这是检测类型不可分配并提供有意义的错误消息的实施质量的情况(或不是)
但是,我们可以期望*在任何实际的'std :: vector'实现中,都会有一个地方试图做一个任务,这会导致一个平坦的编译器错误。事实并非如此,这很有趣。 MSVC实施拉动的是什么技巧? – 2012-04-05 19:32:54
你不想知道g ++吐出了什么错误。 – 2012-04-05 19:34:51
@MrLister:太迟了,我已经烧焦了我的眼睛...... – 2012-04-05 19:35:11
您显然不明白“未定义的行为”中的“未定义”字是什么意思。 – 6502 2012-04-05 19:30:47
奉承会让你无处不在 - 我可以说这更好一点。 – Tabber33 2012-04-05 19:41:08
对不起,我并不是故意冒犯,但通常未定义的行为被误认为是运行时崩溃或编译错误保证。没有什么比真相更遥远。 C++充满了一些看似合理的东西确实被禁止的地方,但编译器并不负责检查。未定义的行为意味着不要这么做......意味着编译器编写者可以自由地假定程序员不会那样做。可能发生的最糟糕的事情实际上只是“没有”......或者直到演示或部署日才说得更好。 – 6502 2012-04-05 19:56:25