In GCC 4.7.0, std::vector<_Tp, _Alloc> internally uses std::_Vector_base<_Tp, _Alloc>::_Vector_impl, which derives from the allocator class (found via std::allocator_traits). If the allocator class is final (in C++11) or has a virtual base that lacks a default constructor, then compilation will fail. The GCC implementation of std::tuple uses the empty base optimization only "for empty, non-final types", so it does not have this problem. * Should I file a bug for adding similar checks in std::vector? It seems unlikely that anyone would use such weird allocators in real programs, especially as std::scoped_allocator_adaptor is explicitly specified to derive from the user's allocator. * In my own templates intended to be portable, what is a good way to apply the empty base optimization only if it is safe? It seems to require an awful lot of boilerplate code, and I don't think __is_final is standard. Here is a sample that demonstrates the errors from giving std::vector an allocator with a virtual base. #include <memory> #include <vector> struct vbase { explicit vbase(int) {} }; template <typename Value> struct nasty: virtual vbase, std::allocator<Value> { template <typename U> struct rebind { typedef nasty<U> other; }; nasty(): vbase(0), std::allocator<Value>() {} nasty(const nasty& other): vbase(0), std::allocator<Value>(other) {} template <typename U> nasty(const nasty<U>& other): vbase(0), std::allocator<Value>(other) {} ~nasty() {} }; std::vector<int, nasty<int> > bob;
Attachment:
pgpNZXx5RMIxX.pgp
Description: PGP signature