Pushed to wwwdocs. --- htdocs/gcc-13/porting_to.html | 60 +++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+)
diff --git a/htdocs/gcc-13/porting_to.html b/htdocs/gcc-13/porting_to.html index 5cbeefb6..f0ccef69 100644 --- a/htdocs/gcc-13/porting_to.html +++ b/htdocs/gcc-13/porting_to.html @@ -144,5 +144,65 @@ done in the i387 floating point stack or are spilled from it. The <code>-fexcess-precision=fast</code> option can be used to request the previous behavior. +<h3 id="alloc-rebind">allocator_traits<A>::rebind_alloc<A::value_type> must be A</h3> + +<p> +GCC 13 now checks that allocators used with the standard library +can be "rebound" to allocate memory for a different type, +as required by the allocator requirements in the C++ standard. +If an allocator type <tt>Alloc<T></tt> +cannot be correctly rebound to another type <tt>Alloc<U></tt>, +you will get an error like this: +</p> + +<pre> +.../bits/alloc_traits.h:70:31: error: static assertion failed: allocator_traits<A>::rebind_alloc<A::value_type> must be A +</pre> + +<p> +The assertion checks that rebinding an allocator to its own value type is a +no-op, which will be true if its <tt>rebind</tt> member is defined correctly. +If rebinding it to its own value type produces a different type, +then the allocator cannot be used with the standard library. +</p> + +<p> +The most common cause of this error is an allocator type <tt>Alloc<T></tt> +that derives from <tt>std::allocator<T></tt> but does not provide its own +<tt>rebind</tt> member. When the standard library attempts to rebind the +allocator using <tt>Alloc<T>::rebind<U></tt> it finds the +<tt>std::allocator<T>::rebind<U></tt> member from the base class, +and the result is <tt>std::allocator<U></tt> instead of +<tt>Alloc<U></tt>. +</p> + +<p> +The solution is to provide a correct <tt>rebind</tt> member as shown below. +A converting constructor must also be provided, so that that an +<tt>Alloc<U></tt> can be constructed from an <tt>Alloc<T></tt>, +and vice versa: +</p> +<pre><code> +template<class T> +class Alloc +{ + Alloc(); + <b> + template<class U> Alloc(const Alloc<U>); + + template<class U> struct rebind { using other = Alloc<U>; }; + </b> + // ... +}; +</code></pre> + +<p> +Since C++20, there is no <tt>rebind</tt> member in <tt>std::allocator</tt>, +so deriving your own allocator types from <tt>std::allocator</tt> is simpler +and doesn't require the derived allocator to provide its own <tt>rebind</tt>. +For compatibility with previous C++ standards, the member should still be +provided. The converting constructor is still required even in C++20. +</p> + </body> </html> -- 2.39.2