Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

mismatched std::allocator for some of STL containers

Is it technically valid to use mismatched std::allocator specialization (surely, except its specialization for void) as a template parameter for STL containers (not all of them, but enumerated below plus unordered_(multi)map/set)? Following code compiles fine.

#include <list>
#include <forward_list>
#include <deque>
#include <set>
#include <map>

int main()
{
    struct A { bool operator < (A) const { return true; } };
    struct B {};
    struct C {};
    std::list< A, std::allocator< C > > l;
    std::forward_list< A, std::allocator< C > > fl;
    std::deque< A, std::allocator< C > > d;
    std::set< A, std::less< A >, std::allocator< C > > s;
    std::multiset< A, std::less< A >, std::allocator< C > > ms;
    std::map< A, B, std::less< A >, std::allocator< C > > m;
    std::multimap< A, B, std::less< A >, std::allocator< C > > mm;
}

I believe this is due to allocator being immediately rebound to underlying node type without any relation to its source type.

like image 479
Tomilov Anatoliy Avatar asked Mar 11 '17 14:03

Tomilov Anatoliy


1 Answers

I'd say this is UB (at least in C++11) because specifying an allocator which has a different value_type from the value_type of the container violates the allocator-aware container requirements which means those instances do not conform to the general container requirements. Furthermore, I can't find anything in the C++11 standard that says that the allocator types are to be rebound from the type provided as template parameter.


 1. Section [container.requirements.general] tells us:

13) All of the containers defined in this Clause and in (21.4) except array meet the additional requirements of an allocator-aware container, as described in Table 99.

 2. The Allocator-aware container requirements says:

Requires: allocator_type::value_type is the same as X::value_type.

  1. Section [default.allocator] specifies

typedef T value_type;

as a member of the allocator template in namespace std.

 4. Section [multimap.overview] contains:

template <class Key, class T, class Compare = less<Key>,
    class Allocator = allocator<pair<const Key, T> > >
class multimap {
    [...]
    typedef Allocator allocator_type;
    [...]
 };

(With similar findings for the other containers.)

like image 99
Pixelchemist Avatar answered Nov 19 '22 15:11

Pixelchemist