Internal typedefs in C++ - good style or bad style

2019-01-29 15:46发布

Something I have found myself doing often lately is declaring typedefs relevant to a particular class inside that class, i.e.

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

//
// ...
//
};

These types are then used elsewhere in the code:

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

lorems.push_back( lorem );

Reasons I like it:

  • It reduces the noise introduced by the class templates, std::vector<Lorem> becomes Lorem::vector, etc.
  • It serves as a statement of intent - in the example above, the Lorem class is intended to be reference counted via boost::shared_ptr and stored in a vector.
  • It allows the implementation to change - i.e. if Lorem needed to be changed to be intrusively reference counted (via boost::intrusive_ptr) at a later stage then this would have minimal impact to the code.
  • I think it looks 'prettier' and is arguably easier to read.

Reasons I don't like it:

  • There are sometimes issues with dependencies - if you want to embed, say, a Lorem::vector within another class but only need (or want) to forward declare Lorem (as opposed to introducing a dependency on its header file) then you end up having to use the explicit types (e.g. boost::shared_ptr<Lorem> rather than Lorem::ptr), which is a little inconsistent.
  • It may not be very common, and hence harder to understand?

I try to be objective with my coding style, so it would be good to get some other opinions on it so I can dissect my thinking a little bit.

9条回答
聊天终结者
2楼-- · 2019-01-29 16:08

Typdefs are definitely are good style. And all your "reasons I like" are good and correct.

About problems you have with that. Well, forward declaration is not a holy grail. You can simply design your code to avoid multi level dependencies.

You can move typedef outside the class but Class::ptr is so much prettier then ClassPtr that I don't do this. It is like with namespaces as for me - things stay connected within the scope.

Sometimes I did

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

And it can be default for all domain classes and with some specialization for certain ones.

查看更多
混吃等死
3楼-- · 2019-01-29 16:09

Typedefs are the ones what policy based design and traits built upon in C++, so The power of Generic Programming in C++ stems from typedefs themselves.

查看更多
唯我独甜
4楼-- · 2019-01-29 16:15

I think it is excellent style, and I use it myself. It is always best to limit the scope of names as much as possible, and use of classes is the best way to do this in C++. For example, the C++ Standard library makes heavy use of typedefs within classes.

查看更多
登录 后发表回答