在C++中正确使用typedef

dic*_*oce 13 c++ typedef

我有同事偶尔使用typedef来避免打字.例如:

typedef std::list<Foobar> FoobarList;
...
FoobarList GetFoobars();
Run Code Online (Sandbox Code Playgroud)

就个人而言,我总是讨厌遇到这样的代码,很大程度上是因为它迫使我去查找typedef所以我可以告诉如何使用它.我也觉得这种事情是一个潜在的滑坡...如果你这样做,为什么你不这样做呢?(很快,你的代码完全被混淆了).我在这个问题上发现了这个问题:

什么时候应该在C中使用typedef

我有两个问题:1)我真的一个人不喜欢这个吗?2)如果绝大多数人认为这种typedef使用正常,你用什么标准来确定是否键入一个类型?

Ecl*_*pse 18

这种类型的两个主要论点typedef是减少了你已经提到过的打字,以及转换到新型容器的难易程度.FoobarList可以由a vector或a list或a 支持,deque并且切换通常只需要更改typedef.

在处理IDE时,你不喜欢它们,因为我只能将鼠标悬停在类型名称上,IDE会告诉我它的定义是什么.

有嵌套容器时更有用的情况 - 您可以给名称赋予一些语义含义,而无需定义整个类:

typedef std::list<Foobar> FoobarList;
typedef std::map <string, FoobarList> GizmosToFoobarsMap;
Run Code Online (Sandbox Code Playgroud)

在处理这些类型的迭代器时,您还可以保存大量的类型(尽管现在C++ 0x已经减少了auto.)

  • 我在过去做过这个,但通常只是因为我正在更改(API类似的)事物的定义,并且不想将std :: vector <foo>的所有外观更改为std: :列表<FOO>.获胜的Typedef.**无论如何,**应该做出一个决定来增加一些代码的可理解性,因此,typedef的实际含义应该与名称本身告诉你的东西无关.例如,当我使用它时,我真的不在乎FooList是std :: list还是std :: vector,除非我需要做一堆插入或随机访问. (3认同)
  • 切换没有typedef的类型时最大的代码更改通常是在甚至不使用类型的层中,只是传递它. (2认同)

Nik*_*sov 9

typedefs对于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;
};
Run Code Online (Sandbox Code Playgroud)

至于typedefs的"快捷方式"用法- 我认为在本地化的实现文件中完全没问题.我在这里有相同的规则using namespace- 如果它可以节省我打字并且不会混淆他人,那就去吧.


Ash*_*ain 7

我喜欢这样的typedef,因为它们提高了可读性.考虑到std::vector<std::string>::const_iterator所有地方,甚至是std::map<std::string, std::vector<std::string> >::iterator.一半的代码最终只是描述类型,而一堆typedef简化了很多.我不认为理解它也是一个障碍太多 - 如果你将鼠标悬停在它上面或定义上,IDE通常可以告诉你类型,并且使用代码通常需要你理解这样的事情.


sbi*_*sbi 5

我喜欢它,typedef因为它允许稍后更改容器的类型(比如,分析显示std::deque更快std::list)而不更改所有相关代码.

如果你想知道:我不反对被称为列表的东西,即使它可能是一个std::deque.在这种情况下,我将"列表"视为概念术语,而不是数据结构.(你不把你的购物清单当成双链表,是吗?)

  • @Pavel:但是,正如其他人所提到的,你的大多数代码都不在乎.它只是传递变量,或使用不改变的结构.当您的代码无法编译时,那些重要的位将立即显示出来.我的经验中最大的担忧是算法专门用于随机访问迭代器,但仍然使用前向迭代器操作; 在这种情况下,建议更改容器的分析可能会建议更改回来. (2认同)