This is the mail archive of the gcc-help@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

empty base optimization vs. final class or virtual base


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: pgp00000.pgp
Description: PGP signature


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]