Default std::vector<bool> default and move constructor
Jonathan Wakely
jwakely@redhat.com
Sat May 27 11:14:00 GMT 2017
On 26/05/17 23:13 +0200, François Dumont wrote:
>On 25/05/2017 18:28, Jonathan Wakely wrote:
>>On 15/05/17 19:57 +0200, François Dumont wrote:
>>>Hi
>>>
>>> Following what I have started on RbTree here is a patch to
>>>default implementation of default and move constructors on
>>>std::vector<bool>.
>>>
>>> As in _Rb_tree_impl the default allocator is not value
>>>initialized anymore. We could add a small helper type arround the
>>>allocator to do this value initialization per default. Should I do
>>>so ?
>>
>>It's required to be value-initialized, so if your patch changes that
>>then it's a problem.
>>
>>Did we decide it's OK to do that for RB-trees? Did we actually discuss
>>that part of the r243379 changes?
>
>I remember a message pointing this issue but after the commit AFAIR. I
>thought it was from Tim but I can't find it on the archive.
>
>What is the rational of this requirement ? I started working on a type
>to do the allocator value initialization if there is no default
>constructor but it seems quite complicated to do so. It is quite sad
>that we can't fully benefit from this nice C++11 feature just because
>of this requirement. If there is any initialization needed it doesn't
>sound complicated to provide a default constructor.
The standard says that the default constructor is:
vector() : vector(Allocator()) { }
That value-initializes the allocator. If the allocator type behaves
differently for value-init and default-init (e.g. it has data members
that are left uninitialized by default-init) then the difference
matters. If you change the code so it only does default-init of the
allocator then you will introduce an observable difference.
I don't see any requirement that a DefaultConstructible allocator
cannot leave members uninitialized, so that means the standard
requires default construction of vector<bool> to value-init the
allocator. Not default-init.
Here's an allocator that behaves differently if value-initialized or
default-initialized:
template<typename T>
struct Alloc {
using value_type = T;
Alloc() = default;
template<typename U>
Alloc(const Alloc<U>& a) : mem(a.mem) { }
T* allocate(std::size_t n) {
if (mem)
throw 1;
return std::allocator<T>().allocate(n);
}
void deallocate(T* p, std::size_t n) {
std::allocator<T>().deallocate(p, n);
}
int mem;
};
template<typename T, typename U>
bool operator==(const Alloc<T>& t, const Alloc<U>& u)
{ return t.mem == u.mem; }
template<typename T, typename U>
bool operator!=(const Alloc<T>& t, const Alloc<U>& u)
{ return !(t == u); }
More information about the Libstdc++
mailing list