typedef和不完全类型 [英] typedef and incomplete type
问题描述
我以前有什么
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 withstd::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 incompletefoo
. - 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 probablyfoo_ref
can not be anything other thanfoo&
, butfoo_ptr
can be. Surprisingly GCC implementation doesn't have nested pointer type fortr1::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屋!