我注意到std::
个容器往往有public
个类内别名(typedef
/ using
)。
例如,请参阅http://en.cppreference.com/w/cpp/container/vector的成员类型。
它们有用吗?当C ++没有像auto
和decltype
这样的东西时,它们不仅仅是一个遗留物吗?
实现自定义容器时,是否应该有typedef
个?如果我没有提供,我会失去什么?
答案 0 :(得分:7)
如果你想要一个与标准库兼容的容器,你必须提供typedef。
如果查看文档,例如在cppreference,你会看到这样的段落:
std :: vector符合Container,AllocatorAwareContainer,SequenceContainer,ContiguousContainer(除了bool之外的T)(自C ++ 17以来)和ReversibleContainer的要求。
如果您查找Container或SequenceContainer或其中列出的任何其他内容,您将找到需求列表,以及typedef(或更确切地说类型 - 它们 不是typedef,尽管他们经常在其中。
因此,如果您在标准意义上构建Container,则需要提供typedef(当然也满足所有其他要求)。
理论上,C ++ 11可以放宽要求,但事实并非如此。也许是因为std::vector<int>::iterator
比
更具可读性decltype(std::declval<std::vector<int>>().begin())
或许是出于其他原因。
答案 1 :(得分:4)
在处理元编程时,它们非常有用。
如果它是POD的容器,让我们通过引用捕获一个容器,而不是它的另一个时间:
template <class T>
typename std::enable_if_t<std::is_pod<typename T::value_type>::value>
doSomething(T& container){
//do something
}
template <class T>
typename std::enable_if_t<!std::is_pod<typename T::value_type>::value>
doSomething(T& container){
//do something
}
我正在为Windows做很多C ++,并且由于Windows API提供了C结构,我使用了许多这样的技术来区分真正的C ++对象和WinApi结构。
答案 2 :(得分:1)
typedef允许将实现与接口分开。
考虑到早期C ++没有定义auto
,因为它现在被定义,而decltype
在标准中不存在。
但即使现在有auto
和decltype
,有时最好明确指定对象的类型。否则代码可能难以阅读,或者可能导致错误。
考虑一个带有类型说明符auto
unsigned int x = 0;
long y = 0;
auto p = new auto( x + y );
你能说出指针p的类型是什么吗?
表达式*p
是无符号类型还是带符号类型?
答案取决于使用过的平台。 p的类型可以是long *
或unsigned long *
。
标准容器存在类似的问题。因此,标准引入了size_type
等通用类型名称,以保证此类型为无符号类型,但其宽度可能因平台而异。
这也允许编写通用代码。
在我的个人资料中,我的文章中提到了一个与标准类std::bitset
没有泛型size_type
相关的问题。在这种情况下,如果您需要将示例类std::vector<bool>
替换为std::bitset
,则需要在使用size_type
或某些显式类型size_t
的地方更改代码。