STL containers require the stored values to be copy constructible and assignable. const T is obviously not an assignable type for any T, but I tried to use it (just being curious) and found out that it compiles and, moreover, behaves as an assignable type.
vector<const int> v(1);
v[0] = 17;
This successfully runs in Visual Studio 2008 and assigns v[0] to 17.
This simply shouldn't work. At §23.1 ¶ 3 it's specified, as you said, that objects stored in a container must beCopyConstructible(as specified at §20.1.3) andAssignable.The
Assignablerequirements for a typeTare that, beingtanduof typeT, you can do:having a
T&as return value andtequivalent touas postcondition. (§23.1 ¶4)Thus,
consttypes are clearly notAssignable, since doingt = uwould raise a compilation error (§7.1.5.1 ¶5).I suppose that this is a bug in Microsoft implementation. g++ on Linux emits the typical 25 kajillion-lines template error if you even try to instantiate a
vector<const int>(tested both with and without the-std=c++0xflag, just in case).By the way, this is also explained in detail in this IBM FAQ.
In theory, as @James McNellis said, the compiler is not required to blow up on the vector instantiation (if it's undefined behavior anything can happen - including everything working fine); however, on the assignation statement there's a violation of the standard that should produce a compilation error.
In facts, the
operator[]member returns avector<const int>::reference; that one is required to be an lvalue ofT(§23.1 ¶5 table 66); sinceTis of aconsttype, it will be aconstlvalue. So we fall down to (§7.1.5.1 ¶5), which defines code that tries to perform an assignment to aconstelement as "ill-formed", and this demands a compilation error or at least a warning, because assignment-to-constis a diagnosable rule (§1.4 ¶1-2) (no "no diagnostic is required" statement is specified).Final edit
Actually, @James McNellis is right; once you've invoked undefined behavior by instantiating
vector<const int>, the usual rules stop having value, so the implementation is still standard-conforming whatever it does - including removing theconstfrom the element type or generating the usual nasal demons.