标准::矢量<T>::value_type的正确行为

Correct behaviour for std::vector<T>::value_type

本文关键字:type gt lt 矢量 标准 value      更新时间:2023-10-16

在对一些使用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");

以上断言失败

std::vector<T>value_typeT(§23.3.6.1)。

is_same的值考虑了cv限定符(§20.9.6)。

在您的情况下,这意味着检查std::is_same<int, int const>,这应该失败。

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

的cv限定符。
std::vector<const int>::value_type val = 5;
val = 10;

在MSVC2008上可以编译,但在gcc 4.4上无法编译。

你应该向微软提交一份bug报告。

编辑: Nawaz上面的评论让我思考。根据这个问题const int确实是允许作为一个value_type在c++ 03!似乎在c++ 11中。虽然在c++ 11中没有明确禁止vector,但在分配器中是禁止的(§17.6.3.5),这反过来又使得vector也是非法的。

无论如何,MSVC静默删除const的行为在这里似乎是错误的。

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

问题是标准容器(例如std::vector)没有设计成容纳const T,因为它们依赖于分配器和[allocator]中的标准。只定义了非const、非引用对象类型的分配器行为。

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

请参阅这个问题,这个答案和Howard Hinnant对此的评论,我引用了第一句话:

底线:我们没有设计容器来容纳const T

看来std::vector<const int>是不允许的:按照标准T应该是CopyInsertable, const int不是。

参见序列容器要求, 23.2.3序列容器[Sequence。

OP代码无法在

行同时使用gcc 4.7和icc 13.0进行编译

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

显然,MSVC丢弃了const限定符