enum no cabeçalho causa recompilações excessivas

John Lakos refere-se a esse problema comouma fonte insidiosa de acoplamento em tempo de compilação (Figura 0-3, em sua introdução):

O problema que estou enfrentando é que muitos arquivos são compilados porque existe uma dependência física de uma única enumeração.

Eu tenho um cabeçalho com a definição de enum:

// version.h
enum Version {
    v1 = 1,
    v2, v3, v4, v5, ... v100
};

e isso é usado por centenas de arquivos. Cada arquivo define uma classe de objetos, que devem ser lidos no disco, usando oread() função.Version é usado para determinar a maneira como os dados devem ser lidos.

Toda vez que uma nova classe ou membro da classe é introduzida, uma nova entrada é anexada à enumeração

// typeA.cpp
#include "version.h"

void read (FILE *f, ObjectA *p, Version v) 
{
    read_float(f, &p->x);
    read_float(f, &p->y);
    if (v >= v100) { 
        read_float(f, &p->z);  // after v100 ObjectA becomes a 3D
    }
}

e

// typeB.cpp
#include "version.h"

void read (FILE *f, ObjectB *p, Version v)
{
    read_float (f, &p->mass);
    if (v >= v30) {
        read_float (f, &p->velocity);
    }
    if (v >= v50) {
        read_color (f, &p->color);
    }
}

Agora, como você pode ver, uma vezObjectA alterações, temos que introduzir uma nova entrada (digamosv100) aoVersion. Consequentemente, todostype*.cpp arquivos serão compilados, mesmo que apenasread() doObjectA realmente precisa dov100 entrada.

Como posso inverter a dependência da enum, com alterações mínimas no cliente (ou seja,type*.cpp), para que apenas os arquivos .c necessários sejam compilados?

Aqui está uma solução possível, em que pensei, mas preciso de uma melhor:

Eu estava pensando em colocar o enum em um arquivo .cpp e exporints com os valores dos respectivos membros enum:

//version.cpp
enum eVersion {
    ev1 = 1,
    ev2, ev3, ev4, ev5, ... ev100
};

const int v1 = ev1;
const int v2 = ev2;
....
const int v100 = ev100;   // introduce a new global int for every new entry in the enum

faça um alias para oVersion digite de alguma forma

//version.h
typedef const int Version;

e introduza apenas os valores constantes que são necessários a cada vez:

// typeA.cpp
#include "version.h"

extern Version v100;    ///// *** will be resolved at link time

void read (FILE *f, ObjectA *p, Version v) 
{
    read_float(f, &p->x);
    read_float(f, &p->y);
    if (v >= v100) { 
        read_float(f, &p->z);  // after v100 ObjectA becomes a 3D
    }
}

mas acho que isso parece uma solução muito ruim, que remonta aos tempos anteriores ao cabeçalho

questionAnswers(2)

yourAnswerToTheQuestion