【发布时间】:2010-06-19 08:15:12
【问题描述】:
最近,当我更改代码中的某些容器、分配器时,我遇到了很多关于 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_type、pointer、reference、iterator等不依赖于T的完整性,并且知道没有完整类型就无法实例化类,那么这样的typedef如何以独立于特定容器或分配器的通用方式制作?
注意:
- 为了完整起见,在“真实”代码中,我使用带有
vector的小型本地内存,而不是用std::array替换它,尽管问题仍然存在。 -
stack_alloc代码远未完成,仅显示部分问题。 - 我知道数组、sizeof 等需要完整的可用类型。但我没有创建
all_foos类型的对象,但foo不完整。 - 我的断言是指针、引用等不应依赖于类型的完整性。否则无法定义像
struct foo{ foo_ptr p;};这样的构造。虽然可能foo_ref不能是foo&以外的任何东西,但foo_ptr可以。令人惊讶的是,GCC 实现没有tr1::array的嵌套指针类型。 - 主要知道什么不能做,并且有兴趣知道在这种情况下可以做什么。所以期待一个好的设计作为解决方案。
【问题讨论】: