В последнее время у меня много проблем с typedef и неполным типом, когда я изменил определенные контейнеры, распределители в моем коде.
То, что у меня было ранее
struct foo;//incomplete type.
typedef std::vector<foo> all_foos;
typedef all_foos::reference foo_ref;
Хотя не совсем не уверен,приведенные выше строки являются законными, но это работало на каждой реализации, которую я использовал.Когда я подумал, что могу выполнить работу с std::tr1::array
, изменил две вышеупомянутые строки на
typedef std::tr1::array<foo,5> all_foos;
typedef all_foos::reference foo_ref;
Здесь все ломается, так как компилятор пытается создать экземпляр array
и терпит неудачу, поскольку foo
не завершентип.Все, что мне было нужно, это ссылка на foo
, и он не особо интересовался «другими частями» массива.foo определенно будет полностью доступен, когда я создаю такой массив.
То же самое проблема, когда typedef std::allocator<foo>::pointer foo_ptr
был заменен на typedef stack_alloc<foo,10>::pointer foo_ptr
.где реализация stack_alloc
похожа на
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;
};
Предполагая, что value_type
, pointer
, reference
, iterator
и т. д. не зависят от полноты T
, и зная, чтокласс не может быть создан без завершенного типа, как такая typedef может быть сделана общим способом независимо от конкретного контейнера или распределителя?
ПРИМЕЧАНИЕ:
- Просто для полноты, в «реальном» коде я использую небольшую локальную память с
vector
вместо ее замены на std::array
, хотя проблема остается той же. stack_alloc
код далек от завершения и показывает только часть проблемы. - Я знаю, что массив, sizeof и т. Д. Должен иметь полный доступный тип.Но я НЕ создаю объект типа
all_foos
с неполным foo
. - Я утверждаю, что указатель, ссылка и т. Д. Не должны зависеть от полноты типа.В противном случае конструкция типа
struct foo{ foo_ptr p;};
не может быть определена.Хотя, вероятно, foo_ref
не может быть ничем иным, чем foo&
, но foo_ptr
может быть.Удивительно, но реализация GCC не имеет вложенного типа указателя для tr1::array
. - В основном знают, что нельзя сделать, и заинтересованы знать, что можно сделать в этой ситуации.Поэтому ожидаем хорошего дизайна в качестве решения.