代码之家  ›  专栏  ›  技术社区  ›  abir

typedef和不完整类型

  •  8
  • abir  · 技术社区  · 14 年前

    最近,当我更改代码中的某些容器、分配器时,我遇到了许多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

    当typedef std::allocator<foo>::pointer foo_ptr 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 etc不依赖于 T

    注:

    • 为了完整起见,在“真实”代码中,我使用了一个小的本地内存 vector std::array
    • 堆栈分配 代码远未完成,仅显示问题的一部分。
    • 我知道数组、sizeof等需要完整的可用类型。但我不是在创建类型的对象 all_foos .
    • struct foo{ foo_ptr p;}; 无法定义。虽然可能 foo_ref 不能是别的 foo& ,但是 foo_ptr 可以是。令人惊讶的是,GCC实现没有嵌套的指针类型 tr1::array .
    • 主要知道什么不能做,并有兴趣知道什么可以在这种情况下做。所以期待一个好的设计作为解决方案。
    2 回复  |  直到 14 年前
        1
  •  8
  •   GManNickG    14 年前

    类型必须完整才能在标准容器中使用,否则行为未定义(§17.4.3.6/2). 所以唯一的标准解决方案是不要这样做 typedef 直到类被定义。

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

    在任何情况下,您都必须首先定义完整的类型,真的。得到一个 类型定义 被实例化,这意味着 整个的 东西必须能用 T 根据需要。

    stack_alloc 一定有 T sizeof(T) 否则类不能被实例化。如果类不能被实例化,就不能得到 从中解脱出来。因此,你会 去拿那个 类型定义 如果 不完整。

        2
  •  3
  •   Dark    14 年前

    typedef std::tr1::array<foo*, 5> all_foos; )而不是对象本身的实例解决了这个问题。