在使用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");
上述断言失败。
答案 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)
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,CopyInsertable
和const int
不是。
参见草案N3485中23.2.3序列容器[sequence.reqmts]的序列容器要求。
OP代码无法使用gcc 4.7和icc 13.0在
行编译 typedef std::vector<int const>::value_type t2;
显然,MSVC会丢弃const限定符。