I'm trying to rebind my custom allocator type, MyAllocator<foo>
, for use in a basic_string
class, e.g.:
std::basic_string<char, std::char_traits<char>, MyAllocator<char>> ...
The allocator is passed to the context as MyAllocator<void>
, so I need to rebind the allocator.
From the cppreference page for std::allocator_traits
, http://en.cppreference.com/w/cpp/memory/allocator_traits:
Member alias templates:
rebind_alloc<T>
:Alloc::rebind<T>::other
if present, otherwiseAlloc<T, Args>
if this Alloc isAlloc<U, Args>
My custom allocator implements allocator_traits
, but does not define the rebind struct (which doesn't appear to be a requirement to implement allocator_traits
). My understanding of the documentation is that it allocator_traits
should understand rebind_alloc
. However, if I try calling rebind_alloc
on my custom allocator type:
template<typename T>
using RebindAlloc =
typename std::allocator_traits<MyAllocator<void>>::template rebind_alloc<T>;
I get various compiler errors when I try to pass RebindAlloc<char>
to the basic_string
type:
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;
Clearly the documentation has misled me. Should I just give up on rebind_alloc
and implement rebind in the custom allocator, or is there a correct way of doing this using allocator_traits
?
I am using gcc 4.8 with C++11. 14 is not an option at the moment.
Here's a code snippet of what I'm trying to do: https://gist.github.com/jacquelinekay/0cee73d1d2d78d8edd31
I am using gcc 4.8 with C++11.
Then you need to define rebind
in your allocator, GCC's basic_string
doesn't support the C++11 allocator requirements until version 5.1 (and then only for the new ABI string, i.e. std::__cxx::basic_string
).
So your allocator must meet the C++03 Allocator requirements, defining all the members, because allocator_traits
isn't used by string in 4.8
n3376 says in [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>
ifAlloc
is a class template instantiation of the formAlloc<U, Args>
, whereArgs
is zero or more type arguments; otherwise, the instantiation ofrebind_alloc
is ill-formed.
which agrees with cppreference. It (allocator traits) seem to have been added in C++11, so it does not appear in n1905. Further archaeology could detect where it arrived, but that isn't all that relevant.
It appears as if your compiler is not a compliant C++11 compiler in this regard.
With minor fixes, both gcc 5.2.0 and clang 3.7.0 in C++11 mode will compile your code without error.
It appears the only reasonable response, if you cannot change your compiler, is to implement a simple rebind
.
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