liz*_*isk 12 c++ stl const visual-c++-2008 visual-c++
STL容器要求存储的值可以复制构造和分配.const T显然不是任何T的可分配类型,但我试图使用它(只是好奇)并发现它编译,而且,表现为可分配类型.
vector<const int> v(1);
v[0] = 17;
Run Code Online (Sandbox Code Playgroud)
这在Visual Studio 2008中成功运行,并将v [0]分配给17.
Jam*_*lis 12
这不是其他人建议的实施中的错误.
违反C++标准库工具的要求不会导致程序格式错误,从而产生未定义的行为.
您违反了存储在容器中的值类型必须是可复制构造和可分配的要求(const显然类型不可分配),因此您的程序会显示未定义的行为.
可以在C++ 03 17.4.3.6 [lib.res.on.functions]中找到C++标准中适用的语言:
在某些情况下(替换函数,处理函数,用于实例化标准库模板组件的类型的操作),C++标准库依赖于C++程序提供的组件.如果这些组件不符合要求,则标准对实施没有要求.
特别是,在以下情况下,效果未定义:
...
- 对于在实例化模板组件时用作模板参数的类型,如果该类型上的操作未实现适用的Requirements子句的语义.
Visual C++标准库实现可以对此代码执行任何操作,包括静默删除或忽略const限定,并且它仍然符合标准.
\n这根本不应该起作用。正如您所说,在 \xc2\xa723.1 \xc2\xb6 3 中指定了存储在容器中的对象必须是CopyConstructible(如 \xc2\xa720.1.3 中指定的那样)并且Assignable。
Assignable类型的要求是T:beingt和uof typeT,您可以执行以下操作:
t = u\nRun Code Online (Sandbox Code Playgroud)\n\n有一个T&作为返回值并且t等价于uas 后置条件。(\xc2\xa723.1\xc2\xb64)
因此,const类型显然不是Assignable,因为这样做t = u会引发编译错误 (\xc2\xa77.1.5.1 \xc2\xb65)。
我认为这是微软实施中的一个错误。如果您尝试实例化一个vector<const int>(使用和不使用-std=c++0x标志的情况下进行测试,以防万一)。
顺便说一句,这在IBM FAQ中也有详细解释。
\n\n理论上,正如 @James McNellis 所说,编译器不需要在向量实例化上崩溃(如果它是未定义的行为,任何事情都可能发生 - 包括一切正常);但是,在赋值语句中违反了标准,应该会产生编译错误。
\n\n事实上,该operator[]成员返回一个vector<const int>::reference; 该值必须是T(\xc2\xa723.1 \xc2\xb65 表 66) 的左值;因为T是一种const类型,所以它将是一个const左值。因此,我们归结为 (\xc2\xa77.1.5.1 \xc2\xb65),它将尝试对元素执行赋值的代码定义为const“格式错误”,这需要一个编译错误或至少一个警告,因为分配给 -const是可诊断规则 (\xc2\xa71.4 \xc2\xb61-2) (未指定“无需诊断”语句)。\n
最终编辑
\n\n事实上,@James McNellis 是对的;一旦您通过实例化调用了未定义的行为vector<const int>,通常的规则就不再有价值,因此无论它做什么,实现仍然符合标准 - 包括删除const从元素类型中删除 或生成通常的鼻恶魔。
| 归档时间: |
|
| 查看次数: |
614 次 |
| 最近记录: |