Open miyuki opened 3 years ago
This is similar to #51816 but this issue more generic (covers all node based containers). Similar to my comment there I think the problem boils down to the custom allocator not having rebind_alloc
nor there being a allocator_traits
specialization for it. Modifying the repro to contain:
template <typename T>
struct alloc : public std::allocator<T> {
// re-use ctors
using std::allocator<T>::allocator;
alloc() { n_alloc++; };
};
namespace std
{
template <typename T>
struct allocator_traits<alloc<T>> : public allocator_traits<std::allocator<T>>
{
template <typename U>
using rebind_alloc = alloc<U>;
};
} // namespace std
I get results that are closer to your expectations, but with libstdc++
interestingly depend on the selected standard mode (all with godbolt's clang trunk):
-std=c++17 -stdlib=libc++
and -std=c++20 -stdlib=libc++
n_alloc: 1
n_alloc: 3
n_alloc: 4
n_alloc: 5
n_alloc: 6
n_alloc: 8
-std=c++17 -stdlib=libstdc++
n_alloc: 1
n_alloc: 2
n_alloc: 2
n_alloc: 3
n_alloc: 4
n_alloc: 4
-std=c++20 -stdlib=libstdc++
n_alloc: 1
n_alloc: 2
n_alloc: 3
n_alloc: 4
n_alloc: 5
n_alloc: 6
Extended Description
Consider the following code:
https://godbolt.org/z/Tn73Me
In [forwardlist.overview], the default constructor is specified as follows: forward_list() : forward_list(Allocator()) { }
Similarly for other containers.
So, the expected output of the above program is:
But with libc++ (recent trunk version) the output is: