typedef和不完整类型

时间:2010-06-19 08:15:12

标签: c++ typedef

最近,当我在代码中更改了某些容器​​,分配器时,我遇到了很多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_typepointerreferenceiterator等不依赖T的完整性,并且知道班级不能实例化没有完整类型,如何以通用方式独立于特定容器或分配器来制作这样的typedef?

注意:

  • 为了完整起见,在'真实'代码中,我使用vector的小本地内存,而不是将其替换为std::array,但问题仍然存在。
  • stack_alloc代码远未完成,只显示问题的一部分。
  • 我知道数组,sizeof等需要完整的类型。但我不是创建all_foos类型的对象,其中foo不完整。
  • 我的断言是指针,引用等不应该依赖于类型的完整性。否则无法定义类似struct foo{ foo_ptr p;};的构造。虽然foo_ref可能不是foo&,但foo_ptr可能不是tr1::array。令人惊讶的是,GCC实现没有{{1}}的嵌套指针类型。
  • 主要了解不能做什么,并有兴趣知道在这种情况下可以做些什么。所以期待一个好的设计作为解决方案。

2 个答案:

答案 0 :(得分:7)

必须完成一个类型才能在标准容器中使用,或者行为未定义(§17.4.3.6/ 2)。因此,唯一的标准解决方案是在定义类之前不要使用typedef

我没有得到中间容器的用途:

struct foo;//incomplete type.
typedef foo& foo_ref;

在任何情况下,你都必须首先定义完整的类型。要在类中定义typedef,必须实例化该类,这意味着整个事物必须能够根据需要使用T

例如,stack_alloc必须T为完整类型(sizeof(T)才能生效),否则无法实例化该类。如果无法实例化该类,则无法从中获取typedef。如果typedef不完整,你永远不会从中获取T

答案 1 :(得分:2)

Compiller不知道不完整类型的大小,因此它不能实例化它也不能为它分配一些内存。拥有指向对象的指针(如typedef std::tr1::array<foo*, 5> all_foos;)而不是对象本身的实例可以解决这个问题。