17

The following code compiles OK using Visual Studio 2013.

#include <vector>
#include <string>

int main()
{
    const std::string constString("fred");
    const std::vector<const std::string> myVector{ constString };
}

If I try to compile it using Visual Studio 2015 the following error is reported:

1>xmemory0(587): error C2338: The C++ Standard forbids containers of const elements because allocator<const T> is ill-formed.

I've seen various posts, and in particular this one Does C++11 allow vector<const T>?, about vector<const T> and why it's not allowed but I don't really get it. However, in the above example the vector itself is const.

Can someone please explain? Is VS 2013 wrong to compile it successfully?

Cœur
  • 37,241
  • 25
  • 195
  • 267
ksl
  • 4,519
  • 11
  • 65
  • 106
  • If you don't believe the answer that you linked and especially the comments what would it take to convince you? Howard Hinnant was on the C++11 committee. – stark Sep 30 '15 at 11:43
  • 2
    Not a helpful comment. Nowhere does it say I don't believe the answer given, and I did say I don't really get it. Furthermore, myVector is const, which isn't discussed and VS2013 compiles the code. – ksl Sep 30 '15 at 12:42
  • 5
    It doesn't matter that the vector is const - it still needs to allocate memory in its constructor, for the sole element you want to put into it - and, as the error message suggests, the problem is precisely with the allocator. Clearly it's a diagnostic added in VS2015 that VS2013 lacked, so yes, VS2013 is wrong to compile it successfully. – Igor Tandetnik Sep 30 '15 at 12:53
  • It also compiles using Xcode 6.2 - hence my confusion. – ksl Sep 30 '15 at 12:55
  • 11
    When a vector grows beyond capacity, it allocates a new array and copies all elements to the new array. This requires the elements to be [copy assignable](http://en.cppreference.com/w/cpp/concept/CopyAssignable). A const type is by definition not copy assignable (not assignable at all). – rustyx Oct 22 '15 at 09:35
  • 2
    @rustyx: ever heard of a copy constructor? – Violet Giraffe Jun 24 '16 at 07:27
  • Doesn't this have something to do with std::strings actually getting typed to std::basic_string, so it's vector that is actually ill formed? I want to say I remember this being problematic with templating and std::string, just can't remember the details. – JoeManiaci Apr 02 '18 at 18:51

1 Answers1

2
Standard   Requirement for T
========   =================
C++03      any type
C++11      any non-const, non-reference object type
C++14      any non-const object type
C++17      any cv-unqualified object type

Nowhere in the standard does it make an exception for
when the container itself is const

So yes, VS 2013 is wrong to compile it successfully.

sp2danny
  • 7,488
  • 3
  • 31
  • 53