std :: vector <t> :: value_type </t>的正确行为

时间:2013-05-02 05:06:07

标签: c++ visual-c++ c++11

在使用std::vector::value_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");

上述断言失败。

3 个答案:

答案 0 :(得分:9)

value_type的{​​{1}}为std::vector<T>(§23.3.6.1)。

T的值考虑了cv限定符(第20.9.6节)。

在你的情况下,这意味着检查is_same,这应该是失败的。

这反过来意味着您根据标准观察到的行为是错误的。似乎MSVC正在为value_type删除cv限定符:

std::is_same<int, int const>

这在MSVC2008上编译但在gcc 4.4中失败。

您应该向Microsoft提交错误报告。

编辑: Nawaz上面的评论让我思考。根据{{​​3}} std::vector<const int>::value_type val = 5; val = 10; 确实允许作为C ++ 03中的value_type! 虽然它是在C ++ 11中。。虽然在C ++ 11中没有明确禁止向量,但禁止使用分配器(第17.6.3.5节),这反过来也使得它对于向量也是非法的。

无论如何,MSVC默默地放弃const int的行为在这里似乎是错误的。

答案 1 :(得分:3)

例如,GCC 4.7.2甚至在它到达static_assert之前就无法编译OP代码。

问题是标准容器(例如std::vector)不是为了保持const T而设计的,因为它们依赖于分配器,[allocator.requirements]中的标准只定义了非const的分配器行为,非参考对象类型。

据我了解,这意味着使用std::vector<const int>会产生未定义的行为。因此,两个编译器都是对的!

另见this问题,this回答和Howard Hinnant对此的评论,我引用了第一篇文章:

  

结论:我们没有设计容器来容纳const T

答案 2 :(得分:1)

在我看来std::vector<const int>是不允许的:根据标准T,CopyInsertableconst int不是。

参见草案N3485中23.2.3序列容器[sequence.reqmts]的序列容器要求

OP代码无法使用gcc 4.7和icc 13.0在

行编译

typedef std::vector<int const>::value_type t2;

显然,MSVC会丢弃const限定符。