C ++中的内部typedef – 风格好还是风格不好?

我发现自己最近经常做的事情是声明与该类中的特定类相关的typedef,即

class Lorem { typedef boost::shared_ptr<Lorem> ptr; typedef std::vector<Lorem::ptr> vector; // // ... // }; 

这些types然后在代码中的其他地方使用:

 Lorem::vector lorems; Lorem::ptr lorem( new Lorem() ); lorems.push_back( lorem ); 

我喜欢它的理由:

  • 它减less了由类模板引入的噪声, std::vector<Lorem>变成了Lorem::vector
  • 它作为一个意图声明 – 在上面的例子中,Lorem类旨在通过boost::shared_ptr引用计数并存储在一个向量中。
  • 它允许实现改变 – 例如,如果需要改变Lorem,以便在后期对引用计数(通过boost::intrusive_ptr )进行入侵式引用计数,那么这将对代码产生最小的影响。
  • 我认为它看起来更漂亮,可以说比较容易阅读。

我不喜欢的原因:

  • 如果你想在另一个类中embedded一个Lorem::vector ,但是只需要(或者想)转发declare Lorem(而不是在头文件中引入依赖),那么你最终会必须使用显式types(例如boost::shared_ptr<Lorem>而不是Lorem::ptr ),这有点不一致。
  • 这可能不是很常见,因此难以理解?

我试着用自己的编码风格来客观,所以最好能有一些其他的意见,所以我可以稍微剖析一下我的想法。

我认为这是优秀的风格,我自己使用它。 尽可能地限制名字的范围总是最好的,类的使用是在C ++中做到这一点的最好方法。 例如,C ++标准库大量使用类中的typedef。

Typedef是C ++中基于策略的devise和特性的基础,因此C ++中的generics编程的力量来源于typedef本身。

它作为一个意图声明 – 在上面的例子中,Lorem类旨在通过boost :: shared_ptr引用计数并存储在一个向量中。

这正是它不能做到的。

如果我在代码中看到'Foo :: Ptr',我完全不知道它是一个shared_ptr还是Foo *(STL has ::指针typedef是T *,请记住)或其他。 ESP。 如果它是一个共享指针,我根本不提供typedef,但明确地保持shared_ptr在代码中的使用。

其实,我很less使用Template Metaprogramming之外的typedef。

STL一直都在做这种事情

根据成员函数和嵌套typedef定义概念的STLdevise是一个历史的死胡同,现代的模板库使用免费的函数和特征类(参考Boost.Graph),因为它们不排除内置types对这个概念进行build模,因为它使得那些没有用给定模板库的概念devise的types变得更容易。

不要使用STL作为犯同样错误的理由。

Typdefs绝对是很好的风格。 而你所有的“我喜欢的原因”是好的和正确的。

关于你遇到的问题。 那么,前向宣言不是一个圣杯。 你可以简单地devise你的代码,以避免多层次的依赖。

你可以在类之外移动typedef,但Class :: ptr比ClassPtr漂亮得多,所以我不这样做。 就像我的命名空间一样 – 事物在范围内保持连接。

有时候我做了

 Trait<Loren>::ptr Trait<Loren>::collection Trait<Loren>::map 

它可以是所有域类的默认值,也可以是某些特定类的特定值。

STL始终执行这种types的操作 – typedef是STL中许多类的接口的一部分。

 reference iterator size_type value_type etc... 

所有的typedef都是各种STL模板类的接口的一部分。

另一个投票是一个好主意。 编写一个在时间和空间上都必须高效的模拟程序时,我开始这样做。 所有的值types都有一个Ptr typedef,它起始于一个boost共享指针。 然后,我做了一些分析,并将其中的一些更改为boost侵入指针,而不必更改这些对象所使用的任何代码。

请注意,这只有当你知道哪些类将被使用,并且所有用途具有相同的要求时才起作用。 例如,我不会在库代码中使用它,因为在编写库时,无法知道它将被使用的上下文。

我build议在课堂外移动这些typedef。 这样,您就可以删除对共享指针和向量类的直接依赖关系,只有在需要时才可以包含它们。 除非在类实现中使用这些types,否则我认为它们不应该是内部types定义。

你喜欢它的原因仍然是匹配的,因为它们是通过typedeftypes别名来解决的,而不是在类中声明它们。

目前我正在研究代码,密集使用这些typedef。 到目前为止,这很好。

但是我注意到,经常有迭代types定义,这些定义被分成了几个类,你永远不知道你正在处理什么types。 我的任务是总结隐藏在这些typedef背后的一些复杂数据结构的大小 – 所以我不能依赖现有的接口。 结合三到六层的嵌套命名空间,然后变得混乱。

所以在使用之前,需要考虑一些问题

  • 其他人是否需要这些typedef? 这个class是否被其他class用了很多?
  • 我是否缩短使用量或隐藏课程? (在隐藏的情况下,你也可以想到接口。)
  • 其他人正在使用代码吗? 他们是如何做到的呢? 他们会觉得更容易,还是会感到困惑?

当typedef只用于类本身(即被声明为private)时,我认为它是一个好主意。 然而,正是由于你给的原因,如果typedef需要在课堂外被认识,我不会使用它。 在这种情况下,我build议在课堂之外把他们搬走。