Take the following code snippet:
#include <vector>
std::vector<int> good;
//illegal, because std::allocator<const T> is ill-formed
std::vector<const int> bad;
//fails to compile under MSVS 2017
std::vector<const int, my_custom_allocator> X;
Why does X fail to compile? MSVS 2017 shows
Error C2338 (failed static assert): The C++ Standard forbids containers of const elements because allocator is ill-formed.
It is my understanding that this is not necessarily correct.
According to 20.5.3.5 [allocator.requirements] (and many SO questions), an allocator of a const T is ill-formed - but as I understand it, it is also possible to define an allocator that only works with a single type (meaning, a non-templated allocator). This avoids, albeit in a slightly pedantic way, the language restriction. It is also my understanding that since templates are instantiated at compile time, the default value for the vector's allocator (i.e., std::allocator<const T>
) is never instantiated - and that, therefore, the last line does not break that rule.
Ignoring the use cases and alternatives (and the fact that const std::vector<int>
probably solves your problem), and given a valid my_custom_allocator
: is std::vector<const int, my_custom_allocator>
really ill-formed?