Recently I am having many problem with typedef and incomplete type when I changed certain containers, allocators in my code.
What I had previously
struct foo;//incomplete type.
typedef std::vector<foo> all_foos;
typedef all_foos::reference foo_ref;
Though not completely not sure whether the above lines are legal, but this worked on every implementation I used. When I thought that I can do the job with std::tr1::array
, changed the above two lines with
typedef std::tr1::array<foo,5> all_foos;
typedef all_foos::reference foo_ref;
Here everything breaks, as the compiler tries to instantiate array
and fails as foo
is incomplete type. What all I needed is a reference to foo
, and not much interested on 'other parts' of the array. foo will definitely be completely available when I create such an array.
The same is problem when typedef std::allocator<foo>::pointer foo_ptr
got replaced by typedef stack_alloc<foo,10>::pointer foo_ptr
. where a stack_alloc
implementation is like
template<typename T,unsigned N>
struct stack_alloc
{
typedef T* pointer;
typedef std::tr1::aligned_storage<sizeof(T)*N, std::tr1::alignment_of<T>::value> buffer;
};
Presuming that, value_type
, pointer
, reference
, iterator
etc does not depend on the completeness of T
, and knowing that the class can not be instantiate without complete type, how such typedef can be made in generic way independent of specific container or allocator?
NOTE:
- Just for completeness, in 'real' code I use a small local memory with
vector
rather than replacing it with std::array
, though the problem remains same.
stack_alloc
code is far from complete, and only shows the part of the problem.
- I know that array, sizeof etc needs complete type available. But I am NOT creating object of type
all_foos
with incomplete foo
.
- My assertion is that pointer,reference etc should not depend on completeness of a type. Otherwise construct like
struct foo{ foo_ptr p;};
can not be defined. Though probably foo_ref
can not be anything other than foo&
, but foo_ptr
can be. Surprisingly GCC implementation doesn't have nested pointer type for tr1::array
.
- Know mostly what can not be done, and interested to know what can be done in this situation. So expecting a good design as a solution.
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…