C++ std::vector的正确行为<;T>;::值类型
在对使用了C++ std::vector的正确行为<;T>;::值类型,c++,visual-c++,c++11,C++,Visual C++,C++11,在对使用了std::vector::value\u type的一些模板代码中的一些错误挠头之后,我跟踪到以下内容。根据标准,这是正确的行为,还是MSVC 2012 CTP存在问题 typedef std::vector<int>::value_type t1; typedef std::vector<int const>::value_type t2; static_assert(!std::is_same<t1, t2>::value, "hm
std::vector::value\u type
的一些模板代码中的一些错误挠头之后,我跟踪到以下内容。根据标准,这是正确的行为,还是MSVC 2012 CTP存在问题
typedef std::vector<int>::value_type t1;
typedef std::vector<int const>::value_type t2;
static_assert(!std::is_same<t1, t2>::value, "hmmm");
typedef std::vector::value_type t1;
typedef std::vector::value_type t2;
静态断言(!std::is_same::value,“hmmm”);
上述断言失败。标准向量的
值类型为T
(§23.3.6.1)
的值是相同的
考虑了cv限定符(§20.9.6)
在您的情况下,这意味着检查std::is_same
,这应该是失败的
这反过来意味着根据标准,你观察到的行为是错误的。MSVC似乎正在删除value_type的cv限定符:
std::vector<const int>::value_type val = 5;
val = 10;
std::vector::value_type val=5;
val=10;
这在MSVC2008上编译,但在GCC4.4中失败
您可能应该向Microsoft提交错误报告
编辑:纳瓦兹的上述评论让我思考。根据const int
在C++03中确实不允许作为值类型!
似乎是在C++11中。。虽然在C++11中没有明确禁止向量使用,但对于分配器(§17.6.3.5)是禁止的,这反过来也使得向量使用非法
在任何情况下,MSVC无声地删除
常量的行为在这里似乎是错误的。在我看来std::vector
是不允许的:根据标准,T应该是copyintertable
,而常量int
不是
参见草案中23.2.3序列容器[Sequence.reqmts]中的序列容器要求
OP代码无法在gcc 4.7和icc 13.0的第行编译
typedef std::vector::value_type t2代码>
显然,MSVC丢弃常量限定符。GCC4.7.2,例如,在运算代码到达静态\u断言之前,仍然无法编译运算代码
问题在于,标准容器(例如,std::vector
)没有设计为容纳const T
,因为它们依赖于分配器,[allocator.requirements]中的标准只定义了非常量、非引用对象类型的分配器行为
据我所知,这意味着使用std::vector
会产生未定义的行为。因此,这两个编译器都是正确的
另见问题、答案和Howard Hinnant对此的评论,我引述了第一段:
一句话:我们没有设计容器来容纳const t
在我看来,我希望std::vector
(以及其他容器)能够std::remove_const
,因为它们的值类型
,但这似乎表明它们没有。哼。@MooingDuck:不。按照标准,value\u type
只是T
。它不能删除STON-NESE。问题是:代码< STD::vector < /C> >?G++和CLAN(以及其他C++编译器)对此有何解释?这是一项了不起的调查工作!虽然您的期望对我来说是有意义的,但是,std::vector
并没有标准化。因此,微软可能将其实现为一个扩展(GCC没有),从const int
中剥离const
。我想你可能会认为这确实是标准中未定义的行为,因此微软在技术上可以随心所欲。我仍然想知道,目前的行为是故意的,还是仅仅存在于其中,因为以前没有人抱怨过。引用标准中阻止这种行为的部分的道具,事实上的标准答案并没有这样做。