开发者

where to keep typedef's, should i have repeated typedef's

开发者 https://www.devze.com 2023-03-19 17:17 出处:网络
Say i have three files //first.h typedef typename std::map<Vertex_t*,Vd_t> MapVertexVd_t; //the graph class and ...

Say i have three files

//first.h
typedef typename std::map<Vertex_t*,Vd_t> MapVertexVd_t;
//the graph class and ...
//other useful things related to a graph class

//s开发者_开发百科econd.h
#include "first.h"
class analyzeGraph {
MapVertexVd_t mapVertexVd;

public:
void fillMap();
};

//second.cpp
#include "second.h"
void analyzeGraph::fillMap()
{
//
}

Now the question is should i place:

typedef typename std::map<Vertex_t*,Vd_t> MapVertexVd_t;

in the files second.h and second.cpp for clarity sake. I feel like i'll get confused after some time since i have way too many typedef and typename all over the place in my code.


I find that depending on the circumstances these work out well:

  • For typedefs used across a lot of files, put them in a shared header file (probably with forward declarations, etc.)
  • For typedefs used only by a few functions or methods (in the declaration), place them immediately before the first relevant declaration, and make sure that the functions are declared together.
  • For typedefs used for data in a class or function, place them at the start of the relevant scope so that people reading the code see them first. (And for classes make the visibility of typedefs as low as possible -- private typedefs should remain private.)


No, make sure that the declarations are not duplicated.

The way you made it now is actually pretty good - you have a separate H file with the typedef, and it is included everywhere the type is used. That's how it is supposed to be.

The problem with duplication is that some compilers might not like it even if they are identical. If at some point you have to change the typedef - then you're in a total mess. That is why you should avoid duplicating.


if MapVertexVd_t is used only inside of the analyzeGraph it is better to place the typedef inside of the analyzeGraph class.


In C89 or C99 (or pre-standard C), a repeat of a typedef at the same scope is a compilation error, nuisance though it is. However, C++ is more civilized and allows 'benign redefinition' (see §7.1.3, ¶2, according to Charles Bailey). Despite this licence, one of the Agile (or Pragmatic) Programming mottos is "DRY: Don't repeat yourself", which in this context means you should not write the typedef in more than one header. You could consider creating a header zeroth.h that is included by each of the other headers (first.h, second.h); it should define or forward declare the type Vertex_t; it must either define or include the declaration of Vd_t (as well as specifying the type MapVertexVd_t). It should also include the relevant standard header (<map>) so that the zeroth.h header is self-contained and can be used without further ado by any code that needs it.


Note that C11 also allows benign redefinition of types:

ISO/IEC 9899:2011 §6.7 Declarations

¶3 If an identifier has no linkage, there shall be no more than one declaration of the identifier (in a declarator or type specifier) with the same scope and in the same name space, except that:

  • a typedef name may be redefined to denote the same type as it currently does, provided that type is not a variably modified type;

  • tags may be redeclared as specified in 6.7.2.3.

By contrast, the corresponding section of C99 says:

ISO/IEC 9899:1999 §6.7 Declarations

§3 If an identifier has no linkage, there shall be no more than one declaration of the identifier (in a declarator or type specifier) with the same scope and in the same name space, except for tags as specified in 6.7.2.3.


Avoid repeating the typedef in different translation units, if you later change one of them you will end up with a maintenance nightmare having to chase all places where you defined the same typedef.

My simple rule is define it where it makes sense. In many cases that will be together with some of the related types (maybe with the definition of Vertex_t) and use sensible names for the typedef that indicate what it is. Only if you don't know what Vertex_t or Vd_t are you would need to go back and check what MapVertexVd_t is, and then having a local typedef will not help either (I don't know what Vertex_t or Vd_t represent, but choose sensible names that will ring the bell as to what the type is and what operations you can perform on it).

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号