Is an incomplete vector allowed if no member functions are called? If yes, then when?

Suppose I have an incomplete type

// in foo.hh
struct Hidden;

      

which I want to use as the element type std::vector

. Using union

, I can "defer" queries to the constructor (s) and destructor std::vector

to the union constructor (s) / destructor implementation.

// in foo.hh
struct Public {
  union Defer {
    std::vector<Hidden> v;
    Defer();
    // add copy/move constructor if needed
    ~Defer();
  } d;
};

      

Now I can use Public

by including only foo.hh

and linking to the file (s) implementing Public::Defer::Defer()

and Public::Defer::~Defer()

. Only those who need access to the full definition Hidden

.

Is this legal C ++? If yes, then when?

Background: Question that came up in my answer to another question .

+3


source to share


1 answer


std::vector<T>

Incomplete type creation was T

undefined behavior until C ++ 14. In C ++ 17, this limitation is somewhat relaxed:

[vector.overview] / 3 An incomplete type T

may be used on instantiation vector

if the allocator satisfies the completeness of the allocator requirement 17.6.3.5.1. T

must be completed before any element of the resulting specialization can be specified vector

.



(Note: The default allocator std::allocator

meets these completeness requirements.)

My reading is that as of C ++ 17 it is legal for a translation unit to include your header (the one that forward-declares Hidden

and defines Public

) and define a variable Public pub;

- but not to actually use any members pub.d.v

. Prior to C ++ 17, simply including the header would already cause undefined behavior.

+2


source







All Articles