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
。我想你可能会认为这确实是标准中未定义的行为,因此微软在技术上可以随心所欲。我仍然想知道,目前的行为是故意的,还是仅仅存在于其中,因为以前没有人抱怨过。引用标准中阻止这种行为的部分的道具,事实上的标准答案并没有这样做。