typedef和不完整类型

abi*_*bir 8 c++ typedef

最近,当我在代码中更改了某些容器​​,分配器时,我遇到了很多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 代码远未完成,只显示问题的一部分.
  • 我知道数组,sizeof等需要完整的类型.但我不是创建all_foos不完整类型的对象foo.
  • 我的断言是指针,引用等不应该依赖于类型的完整性.否则构造就像struct foo{ foo_ptr p;};无法定义.虽然可能foo_ref不是其他任何东西foo&,但foo_ptr可以.令人惊讶的是,GCC实现没有嵌套指针类型tr1::array.
  • 主要知道什么是不能做的,并且有兴趣知道在这种情况下可以做些什么.所以期待一个好的设计作为解决方案.

GMa*_*ckG 8

必须完整的类型才能在标准容器中使用,或者行为未定义(§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它.如果不完整的话,你永远不会得到typedefT.