typedef和不完全类型 [英] typedef and incomplete type

查看:174
本文介绍了typedef和不完全类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



我以前有什么

  struct foo; //不完全类型。 
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> 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>缓冲;
};

假设 value_type 指针引用迭代器等不依赖于 T ,并且知道类不能在没有完整类型的情况下被实例化,这样的typedef如何能够以通用方式独立于特定的容器或分配器?



注意:




  • 为了完整性,一个小的本地存储器向量,而不是替换为 std :: array ,尽管问题仍然相同。 li>
  • stack_alloc 代码远未完成,只显示问题的一部分。

  • 知道数组,sizeof等需要完整类型可用。但我不是使用不完整的 foo 创建类型 all_foos 的对象。

  • 我的断言是指针,引用等不应该依赖于类型的完整性。否则不能定义 struct foo {foo_ptr p;}; 的构造。虽然可能 foo_ref 不能是除 foo& 之外的任何东西,但 foo_ptr 可以。令人惊讶的是,GCC实现没有 tr1 :: array 的嵌套指针类型。

  • 知道大多数不能做的事情,知道在这种情况下可以做什么。因此希望有一个好的设计作为解决方案。


解决方案

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



中间容器是什么:

  struct foo; //不完全类型。 
typedef foo& foo_ref;

无论如何,你只需要先定义完整的类型。要在类中定义 typedef ,必须实例化 ,这意味着整个根据需要使用 T



例如, stack_alloc 必须有 T 是一个完整的类型( sizeof(T)才能工作),否则类不能被实例化。如果类不能被实例化,你不能得到 typedef 。如果 T 不完整,您将从不取得 typedef


Recently I am having many problem with typedef and incomplete type when I changed certain containers, allocators in my code.

What I had previously

struct foo;//incomplete type.
typedef std::vector<foo> all_foos;
typedef all_foos::reference foo_ref;

Though not completely not sure whether the above lines are legal, but this worked on every implementation I used. When I thought that I can do the job with std::tr1::array, changed the above two lines with

typedef std::tr1::array<foo,5> all_foos;
typedef all_foos::reference foo_ref;

Here everything breaks, as the compiler tries to instantiate array and fails as foo is incomplete type. What all I needed is a reference to foo, and not much interested on 'other parts' of the array. foo will definitely be completely available when I create such an array.

The same is problem when typedef std::allocator<foo>::pointer foo_ptr got replaced by typedef stack_alloc<foo,10>::pointer foo_ptr. where a stack_alloc implementation is like

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;
};

Presuming that, value_type, pointer, reference, iterator etc does not depend on the completeness of T, and knowing that the class can not be instantiate without complete type, how such typedef can be made in generic way independent of specific container or allocator?

NOTE:

  • Just for completeness, in 'real' code I use a small local memory with vector rather than replacing it with std::array, though the problem remains same.
  • stack_alloc code is far from complete, and only shows the part of the problem.
  • I know that array, sizeof etc needs complete type available. But I am NOT creating object of type all_foos with incomplete foo.
  • My assertion is that pointer,reference etc should not depend on completeness of a type. Otherwise construct like struct foo{ foo_ptr p;}; can not be defined. Though probably foo_ref can not be anything other than foo&, but foo_ptr can be. Surprisingly GCC implementation doesn't have nested pointer type for tr1::array.
  • Know mostly what can not be done, and interested to know what can be done in this situation. So expecting a good design as a solution.

解决方案

A type must be complete to be used in a standard container, or the behavior is undefined (§17​.4.3.6/2). So the only standard solution is to not make that typedef until the class is defined.

I don't get what the intermediate container is for:

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

In any case, you'll just have to have the complete type defined first, really. To get a typedef defined in a class, that class must be instantiated, which means the entire thing must be able to use T as desired.

For example, stack_alloc must have T be a complete type (for sizeof(T) to work), otherwise the class cannot be instantiated. If the class can't be instantiated, you cannot get the typedef out of it. Ergo, you'll never get the typedef out of it if T is incomplete.

这篇关于typedef和不完全类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆