某些STL容器的std :: allocator不匹配

Ori*_*ent 9 c++ containers stl allocator language-lawyer

在技​​术上有效的是使用不匹配的特化std::allocator(当然,除了它的专业化void)作为STL容器的模板参数(不是全部,但下面列举加上无序_(多)映射/集)?以下代码编译正常.

#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;
}
Run Code Online (Sandbox Code Playgroud)

我相信这是由于分配器立即反弹到底层节点类型而与其源类型没有任何关系.

Pix*_*ist 10

我说这是UB(至少在C++ 11),因为确定具有不同的分配器value_typevalue_type所述容器的违反分配器感知容器的需求,这意味着这些实例不符合一般容器的要求.此外,我在C++ 11标准中找不到任何说明分配器类型将从作为模板参数提供的类型中反弹的内容.


 部分[container.requirements.general]告诉我们:

13)本条款和(21.4)中定义的所有容器除阵列外,都满足分配器感知容器的附加要求,如表99所示.

 2. Allocator感知容器要求说:

要求:allocator_type::value_type与...相同X::value_type.

  1. 部分[default.allocator]规定

typedef T value_type;

作为allocator命名空间中模板的成员std.

 4.部分[multimap.overview]包含:

template <class Key, class T, class Compare = less<Key>,
    class Allocator = allocator<pair<const Key, T> > >
class multimap {
    [...]
    typedef Allocator allocator_type;
    [...]
 };
Run Code Online (Sandbox Code Playgroud)

(对于其他容器也有类似的发现.)

  • 附加信息:libc ++在编译时使用`static_assert`捕获此UB. (3认同)