C++ 在C+中正确使用typedef+;
我有一些同事偶尔使用typedef来避免打字。例如:C++ 在C+中正确使用typedef+;,c++,typedef,C++,Typedef,我有一些同事偶尔使用typedef来避免打字。例如: typedef std::list<Foobar> FoobarList; ... FoobarList GetFoobars(); typedef std::list FoobarList; ... FoobarList GetFoobars(); 就个人而言,我总是讨厌遇到这样的代码,主要是因为它迫使我去查找typedef,这样我就可以知道如何使用它。我也觉得这类事情是一个潜在的滑坡。。。如果你这么做,为什么不多做一点呢?
typedef std::list<Foobar> FoobarList;
...
FoobarList GetFoobars();
typedef std::list FoobarList;
...
FoobarList GetFoobars();
就个人而言,我总是讨厌遇到这样的代码,主要是因为它迫使我去查找typedef,这样我就可以知道如何使用它。我也觉得这类事情是一个潜在的滑坡。。。如果你这么做,为什么不多做一点呢?(很快,您的代码就完全混乱了)。关于这个问题,我发现这个问题非常重要:
我有两个问题:1)我真的不喜欢这样吗?2) 如果绝大多数人认为这种类型的typedef使用是可以的,那么你用什么标准来决定是否定义一个类型?这种类型的
typedef
的两个主要参数是你已经提到的减少类型,以及转换为一种新类型的容器的方便性。FoobarList可以由向量
或列表
或deque
支持,切换通常只需要更改typedef
当涉及到查找它们时,您对它们的不喜欢在处理IDE时会大大减少,因为我可以将鼠标悬停在类型名称上,IDE会告诉我它的定义
更有用的情况是当您有嵌套容器时-您可以赋予名称一些语义含义,而无需定义整个类:
typedef std::list<Foobar> FoobarList;
typedef std::map <string, FoobarList> GizmosToFoobarsMap;
typedef std::list FoobarList;
typedef std::map GizmosToFoobarsMap;
在处理这些类型的迭代器时,您还可以节省大量的键入时间(尽管由于C++0x有了
auto
),这一点已经减少了)我在代码中也没有这样做,所以我想您并不孤单。在我看来,还有一件事是读者必须去查阅的。糟糕的代码阅读器通常已经有足够多的了。就我个人而言,我还typedef
STL文件、列表和迭代器(Foos
和footerator
)。在任何地方使用都会形成一种非常清晰(imo)的风格,你会习惯于第二次出现
此外,您只需将鼠标悬停在该类型上,即可查看它在任何真实IDE(vs或eclipse)中的真正含义,因此,除了不必向右滚动3个屏幕即可阅读整行内容外,您还可以在其使用点获得所需的所有信息
有了C++0x
auto
关键字,就不再需要这个了。是的,我相信C#的var
关键字,如果您有疑问,可以再次将鼠标移到它上面查看类型 我喜欢这样的typedef,因为它们提高了可读性。考虑有<代码> STD::vector:StaskIythultAuth/<代码>遍地,或者甚至<代码> STD::MAP::迭代器< /代码>。一半的代码最终只是描述类型,而一堆typedef将其简化了很多。我不认为这对理解任何一个障碍太大了。IDE通常可以告诉你,如果鼠标悬停在它上面或者去定义,并且使用代码通常需要你理解这样的事情。 < P>当你需要编写跨平台工作的C++代码时,你会看到很多类型。因为基本数据类型的大小不是固定的。例如,Java虚拟机具有针对不同编译器的基本类型的typedef。我认为在这种情况下,typedef是一种很好的实践。虽然模板语法将参数放在您面前,但它们通常是在面向对象环境中试图封装的类型
typedef’ing模板执行该封装。
typedef
s通常对STL和模板编程至关重要。看看迭代器特性是如何工作的:
template <class Iterator>
struct iterator_traits {
typedef typename Iterator::iterator_category iterator_category;
typedef typename Iterator::value_type value_type;
typedef typename Iterator::difference_type difference_type;
typedef typename Iterator::pointer pointer;
typedef typename Iterator::reference reference;
};
template <class T>
struct iterator_traits<T*> {
typedef random_access_iterator_tag iterator_category;
typedef T value_type;
typedef ptrdiff_t difference_type;
typedef T* pointer;
typedef T& reference;
};
模板
结构迭代器{
typedef typename迭代器::迭代器\类别迭代器\类别;
typedef typename迭代器::value_type value_type;
typedef typename迭代器::差分类型差分类型;
typedef typename迭代器::指针;
typedef typename迭代器::引用引用;
};
模板
结构迭代器{
typedef随机访问迭代器标记迭代器类别;
类型定义T值_类型;
typedef ptrdiff_t difference_type;
typedef T*指针;
typedef T&reference;
};
至于
typedef
s的“快捷方式”用法,我认为在实现文件中进行本地化是非常好的。我这里的规则与使用名称空间的规则相同-如果这样可以省去我的键入,并且不会混淆其他人,那么就去做吧。我个人发现,typedef在处理模板化代码时非常有用,无论是在编写模板时还是在实例化模板时
编写模板:
模板元编程需要typedef。例如,删除常量:
template<typename T>
struct RemoveConst
{
typedef T Type;
};
template<>
struct RemoveConst<const T>
{
typedef T Type;
};
在这种情况下,您只需要更改IntContainer的typedef,任何引用它的实例都会自动更改。在您的示例中,FoobarList
与任何其他类没有区别;您仍然需要查看定义或文档才能知道如何使用它;你不会用它作为不使用类的理由
在本例中,一旦确定它是STL std::list,您就知道如何使用它,或者至少知道在哪里可以找到高质量的文档;对于项目中定义的大多数类来说,这可能比您所能说的要多
也就是说,我对这是否是一个好主意感到矛盾;我只是认为它基本上是无害的。我喜欢typedef
因为它允许以后更改容器的类型(比如,分析显示std::deque
比std::list
更快)而不必更改所有相关的代码
如果你想知道的话:我并不反对这个东西被称为列表,甚至
typedef std::list<Foobar> FoobarList;
...
FoobarList GetFoobars();
class SomeClass
{
...
std::vector<int> mContainer;
};
for(std::vector<int>::iterator It = mContainer.begin(); It != mContainer.end(); ++It)
{
}
class SomeClass
{
typedef std::vector<int> IntContainer;
...
IntContainer mContainer;
};
for(IntContainer::iterator It = mContainer.begin(); It != mContainer.end(); ++It)
{
}