Reputation: 752
After scratching my head at some errors in some template code that used std::vector::value_type
I tracked it down to the following. Is this correct behavior according to the standard, or is this a problem with 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");
The above assertion fails.
Upvotes: 6
Views: 2074
Reputation: 54589
The value_type
of a std::vector<T>
is T
(§23.3.6.1).
The value of is_same
takes cv qualifiers into account (§20.9.6).
In your case that means checking std::is_same<int, int const>
, which is supposed to fail.
Which in turn means that the behavior you observed is wrong according to the standard. It seems that MSVC is dropping the cv qualifiers for value_type:
std::vector<const int>::value_type val = 5;
val = 10;
This compiles on MSVC2008 but fails with gcc 4.4.
You should probably file a bug report with Microsoft.
Edit: Nawaz's comment above got me thinking. According to this question const int
is indeed not allowed as a a value_type in C++03!
It seems though that it is in C++11.. While it's not explicitly forbidden in C++11 for vectors, it is forbidden for allocators (§17.6.3.5), which in turn makes it illegal for vectors as well.
In any case, MSVC's behavior of silently dropping the const
seems wrong here.
Upvotes: 9
Reputation: 58451
It seems to me std::vector<const int>
is not allowed: According to the standard T shall be CopyInsertable
and const int
isn't.
See Sequence container requirements at 23.2.3 Sequence containers [sequence.reqmts] in the draft N3485.
The OP code fails to compile with both gcc 4.7 and icc 13.0 at the line
typedef std::vector<int const>::value_type t2;
Apparently, the MSVC discards the const qualifier.
Upvotes: 1
Reputation: 20503
GCC 4.7.2, for instance, fails to compile the OP code even before it reaches the static_assert
.
The problem is that standard containers (e.g. std::vector
) were not designed to hold const T
because they depend on allocators and the standard in [allocator.requirements] only defines the allocator behavior for non-const, non-reference object types.
As far as I understand, this means that using std::vector<const int>
yields undefined behaviour. Therefore, both compilers are right!
See also this question, this answer and Howard Hinnant's comment on it, which I quote the first sencence:
Bottom line: We didn't design containers to hold
const T
.
Upvotes: 3