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?
I think it would still be ill-formed. According to [allocator.requirements], an allocator is supposed to work with objects of a type T
which is defined to be
any cv-unqualified object type
Based on that, it would seem to me that anything that works with const T
cannot satisfy the requirements to be an allocator and, thus, cannot be used as an allocator for a standard container…
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With