Domanda

Ho un sacco di codice come questo:

#define WITH_FEATURE_X

struct A {
#ifdef WITH_FEATURE_X
  // ... declare some variables Y
#endif
  void f ();
};

void A::f () {
  // ... do something
#ifdef WITH_FEATURE_X
  // ... do something and use Y
#else
  // ... do something else
#endif
  // ... do something
}

e mi piacerebbe sostituire i # definisce con i parametri del modello:

template < int WITH_FEATURE_X > // can be 0 or 1
struct A;

Ma io non voglio duplicare quasi l'intero codice di A :: f () per A <0> :: f () e A <1> :: f () solo per le poche righe che dipendono il parametro. Anche io non voglio richiamare le funzioni anziché i #ifdefs precedenti. Qual è la soluzione comune?

È stato utile?

Soluzione

Credo che ciò che si vuole è un equivalente del "statico se" il comando che esiste nel linguaggio D. Sono tale caratteristica una paura non esiste in C ++.

Si noti che se parti del codice variano a seconda della funzione richiesta, da queste parti non appartengono nella funzione principale perché non sono parte dell'algoritmo nudo. Quindi, la possibilità di delegare tali caratteristiche nelle funzioni sembra un buon compromesso.

Modifica
Se le sue dichiarazioni #ifdef sono usati per fare la stessa attività secondaria in modo diverso, quindi definendo parziali è la cosa giusta da fare. Si renderà il codice più leggibile, non di meno.

Se vengono utilizzati per azioni completamente diverse, beh, il codice è già ingombra. Fare qualcosa al riguardo.

Per quanto riguarda il problema di prestazioni si teme possa apparire, fidatevi del vostro compilatore.

EDIT2
Ho dimenticato di dire la risposta alla prima parte del codice:. Utilizzare il seguente trucco per aggiungere o rimuovere membri a seconda delle "feature"

namespace helper
{
  template<int feature>
  struct A;

  template<>
  struct A<0> { // add member variables for case 0 };

  template<>
  struct A<1> { // add member variables for case 1 };
}

template<int feature>
class A : private helper::A<feature>
{
  // ... functions here
};

Altri suggerimenti

Se si vuole evitare di duplicare la logica della funzione di f è possibile utilizzare la template metodo modello (no, non quel tipo di template .

template <bool enabled>
class helper {
protected:
    void foo() { /* do nothing */ }
};

template <>
class helper<true> {
protected:
    Y y;
    void foo() { /* do something with y */ }
};

struct A : private helper<WITH_FEATURE_X> {
    void f() {
        // common stuff

        foo(); // optimized away when WITH_FEATURE_X is false

        // more common stuff
    }
};

La soluzione più comune, è solo per uso #ifdef ho paura. : -)

Non capisco il punto della duplicazione codice comune. Se u si utilizza template parametro u sono solo sostituire il #ifdef con se (WITH_FEATURE_X). Sono u parlando di pesantezza del codice dal compilatore. Dal momento che si sta cercando di sostituire #ifdef Io parto dal presupposto che si sarebbe utilizzando un <0> o A <1> in qualsiasi punto. Quindi non vedo un troppo grosso codice, anche dal compilatore.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top