Posso creare un tipo, typedef o usando un'istruzione che si traduca in un tipo diverso se istanziato una seconda volta o più?

0

Supponiamo che abbia una classe che valuti alcune funzioni di calcolo intensivo:

class Value
{
private:
  int eval()
  {
    mCached = ExpensiveOperation();
    return mCached;
  }
  static int mCached;
};

Supponiamo ora che Value sia effettivamente un'espressione di modello, come Plus<1, Multiply<2, 3>> o qualcosa di simile. Può essere annidato e potrebbe apparire più volte come parte di un'espressione più grande.

Non so quale sia l'espressione, ma so do , in base alla sua posizione nell'espressione, che la sua istanza (se ci sono più istanze esattamente dello stesso tipo) essere valutato prima.

Voglio memoizzare il risultato per i tipi successivamente istanziati, in modo che non vengano valutati più di una volta ogni volta che viene valutata l'espressione.

Il modo facile per ottenere questo è memorizzare i risultati nella cache in una sorta di hash_map o usare singleton che controllano se un membro statico è valutato, ma l'allocazione e le ricerche dell'heap sono costose, oltre a conosciamo già i tipi in fase di compilazione e sappiamo quale istanza verrà valutata per prima, quindi perché non preparare la memoizzazione anche in fase di compilazione?

Che cosa succede se abbiamo avuto qualcosa come un tipo Cached , che ha semplicemente tirato il risultato dalla prima classe dello stesso tipo:

template <typename Expression>
class Cached
{
  int eval()
  {
    return Expression::mCached; // cheap!
  }
};

Il problema è che ora devo ricordare di posizionare Cached ovunque se viene ripetuta un'espressione!

// Inefficient but nice expression:
Add<Multiply<2, 3>, Multiply<2, 3>>

// Efficient but ugly expression
Add<Multiply<2, 3>, Cached<2, 3>>;

Come posso creare un'espressione che assomigli all '"inefficiente ma bella espressione" e tuttavia genera automaticamente un tipo Cached ?

    
posta quant 19.09.2014 - 15:58
fonte

2 risposte

1

Se ho compreso correttamente la tua domanda, puoi semplicemente utilizzare una variabile statica locale per archiviare il risultato del costoso calcolo.

class Value
{
private:
  int eval()
  {
    static int mCached = ExpensiveOperation();
    return mCached;
  }
};
    
risposta data 20.09.2014 - 20:19
fonte
0

È possibile esaminare il valore memorizzato nella cache come un oggetto Lazy Singleton.
In questo modo verrà calcolato solo una volta per tipo.

int eval()
  {
    if (mCached == nullptr)
    {
       //Lock here
       if (mCached == nullptr) //double check after lock
       {
          int tempValue = ExpensiveOperation();
          mCached.reset(new int(tempValue));
       }
    }
    return *mCached.get();
  }
static uinque_ptr<int> mCached;
    
risposta data 19.09.2014 - 18:58
fonte

Leggi altre domande sui tag