如果自定义分配器中不存在重新绑定,std::allocator_traits 是否定义 rebind_alloc?

Does std::allocator_traits define rebind_alloc if rebind not present in custom allocator?

我正在尝试重新绑定我的自定义分配器类型 MyAllocator<foo>,以便在 basic_string class 中使用,例如:

std::basic_string<char, std::char_traits<char>, MyAllocator<char>> ...

分配器作为 MyAllocator<void> 传递给上下文,所以我需要重新绑定分配器。

来自 std::allocator_traitshttp://en.cppreference.com/w/cpp/memory/allocator_traits 的 cppreference 页面:

Member alias templates:

rebind_alloc<T>: Alloc::rebind<T>::other if present, otherwise Alloc<T, Args> if this Alloc is Alloc<U, Args>

我的自定义分配器实现了 allocator_traits,但没有定义重新绑定结构(这似乎不是实现 allocator_traits 的必要条件)。我对文档的理解是allocator_traits应该理解rebind_alloc。但是,如果我尝试在我的自定义分配器类型上调用 rebind_alloc

template<typename T>
using RebindAlloc =
  typename std::allocator_traits<MyAllocator<void>>::template rebind_alloc<T>;

当我尝试将 RebindAlloc<char> 传递给 basic_string 类型时出现各种编译器错误:

In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/string:52:
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/basic_string.h:114:41: error: 
  'rebind' following the 'template' keyword does not refer to a template
  typedef typename _Alloc::template rebind<_CharT>::other _CharT_alloc_type;

显然文档误导了我。我应该放弃 rebind_alloc 并在自定义分配器中实现重新绑定,还是有使用 allocator_traits?

的正确方法?

我正在使用带有 C++11 的 gcc 4.8。 14 目前不是一个选项。

这是我正在尝试做的代码片段: https://gist.github.com/jacquelinekay/0cee73d1d2d78d8edd31

n3376 在 [allocator.traits.types]/10 中表示:

template <class T> using rebind_alloc = see below;

Alias template: Alloc::rebind<T>::other if such a type exists; otherwise, Alloc<T, Args> if Alloc is a class template instantiation of the form Alloc<U, Args>, where Args is zero or more type arguments; otherwise, the instantiation of rebind_alloc is ill-formed.

这与 cppreference 一致。它(allocator traits)似乎是在C++11中加入的,所以它没有出现在n1905中。进一步的考古学可以检测到它到达的位置,但这并不是那么重要。

在这方面,您的编译器似乎不是兼容的 C++11 编译器。

通过小的修复,both gcc 5.2.0 and clang 3.7.0 in C++11 mode 将编译您的代码而不会出错。

看来唯一合理的回应是,如果您不能更改您的编译器,那就是实现一个简单的 rebind

I am using gcc 4.8 with C++11.

然后你需要在你的分配器中定义 rebind,GCC 的 basic_string 在 5.1 版之前不支持 C++11 分配器要求(然后只支持新的 ABI 字符串,即std::__cxx::basic_string).

因此您的分配器必须满足 C++03 分配器要求,定义所有成员,因为 allocator_traits 在 4.8

中未被字符串使用