C++ 在C+中正确使用typedef+;

C++ 在C+中正确使用typedef+;,c++,typedef,C++,Typedef,我有一些同事偶尔使用typedef来避免打字。例如: typedef std::list<Foobar> FoobarList; ... FoobarList GetFoobars(); typedef std::list FoobarList; ... FoobarList GetFoobars(); 就个人而言,我总是讨厌遇到这样的代码,主要是因为它迫使我去查找typedef,这样我就可以知道如何使用它。我也觉得这类事情是一个潜在的滑坡。。。如果你这么做,为什么不多做一点呢?

我有一些同事偶尔使用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)
{
}