Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is an STL Container of const T with a custom allocator ill-formed?

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?

like image 364
osuka_ Avatar asked Mar 22 '19 18:03

osuka_


1 Answers

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…

like image 124
Michael Kenzel Avatar answered Nov 05 '22 16:11

Michael Kenzel