最近,当我在代码中更改了某些容器,分配器时,我遇到了很多typedef和不完整类型的问题.
我之前有过的
struct foo;//incomplete type.
typedef std::vector<foo> all_foos;
typedef all_foos::reference foo_ref;
Run Code Online (Sandbox Code Playgroud)
虽然不完全不确定上述行是否合法,但这适用于我使用的每个实现.当我以为我可以完成这项工作时std::tr1::array,改变了以上两行
typedef std::tr1::array<foo,5> all_foos;
typedef all_foos::reference foo_ref;
Run Code Online (Sandbox Code Playgroud)
这里的一切都中断了,因为编译器试图实例化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;
};
Run Code Online (Sandbox Code Playgroud)
假定该,value_type,pointer,reference,iterator等不依赖于的完整性T,以及明知类不能没有完全类型实例化,类型定义怎么这么能在独立于特定的容器或分配器的通用方式进行?
注意:
vector而不是替换它std::array,尽管问题仍然存在.stack_alloc 代码远未完成,只显示问题的一部分.all_foos不完整类型的对象foo.struct foo{ foo_ptr p;};无法定义.虽然可能foo_ref不是其他任何东西foo&,但foo_ptr可以.令人惊讶的是,GCC实现没有嵌套指针类型tr1::array.必须完整的类型才能在标准容器中使用,或者行为未定义(§17?.4.3.6/2).因此,唯一的标准解决方案是在typedef定义类之前不要这样做.
我没有得到中间容器的用途:
struct foo;//incomplete type.
typedef foo& foo_ref;
Run Code Online (Sandbox Code Playgroud)
无论如何,你只需要首先定义完整的类型,真的.要typedef在类中定义,必须实例化该类,这意味着整个事物必须能够T根据需要使用.
例如,stack_alloc必须T是一个完整的类型(用于sizeof(T)工作),否则该类无法实例化.如果无法实例化类,则无法获得typedef它.如果不完整的话,你永远不会得到typedef它T.