Opzionalmente proprietà di runtime

3

Sto cercando informazioni su un pattern che ho usato di recente. L'idea di base è che esiste un tipo con una proprietà che può essere sia in fase di compilazione (parametro template) o runtime (membro). std :: span è un buon esempio di questo modello. Ecco un esempio del modello nella sua forma più pura:

// special “invalid” value
constexpr int runtime = -1;

// compile-time version
template <int Property = runtime>
struct Type {
  static constexpr int getProp() {
    return Property;
  }
};

// runtime version
template <>
struct Type<runtime> {
  int getProp() const {
    return property;
  }
private:
  int property;
};

Di solito finisci con due classi molto simili quindi di solito sollevo codice comune in una classe base usando l'idioma CRTP.

  • Questo modello ha un nome?
  • Se non c'è un buon nome, come dovrei descriverlo? (Il titolo della domanda è il mio miglior tentativo)
  • Qualcuno ha scritto su questo modello da qualche parte?
  • Quando dovrei evitare di usare questo modello?
posta Kerndog73 18.09.2018 - 12:04
fonte

1 risposta

0

OK, mi riferirò solo a 'Quando dovrei evitare di usare questo modello?' :

Tendo a dire "sempre" :

  1. Esiste un valore sentinella (nel caso specifico -1) - cosa succede se ne hai bisogno al momento della compilazione? Quindi dovresti ancora utilizzare la variante di runtime.
  2. Ogni due di Type<n> con valori diversi per n sono tipi diversi e indipendenti. Quindi se intendevi usarli insieme in un contenitore - sfortuna. Ma se non puoi, allora a cosa serve?

Quindi, invece di specializzare un valore speciale (sentinella), andrei con classi totalmente estranee:

template <int Property>
struct CompileTimeType
{
    static constexpr int getProp() { return Property; }
};
struct RunTimeType
{
    int getProp() const { return property; }
private:
    int property;
};

Tieni presente che, come ora, dovresti comunque utilizzare entrambi in modo diverso:

CompileTimeType<whatEver>::getProp();
RuntimeType rtt;
rtt.getProp();

Tutto senza problemi se sai in anticipo che tipo hai. Vuoi usarli nelle funzioni dei modelli? Bene, una volta, hai bisogno di un'istanza, l'altra no. Hmm ... - Vuoi ancora avere un'istanza per la variante del tempo di compilazione? Quindi puoi rendere la funzione non statica.

Se vuoi combinare combinazioni arbitrarie di istanze comte e run time in un contenitore, avrai comunque bisogno di una classe base comune (anche per diverse istanze di tempo di compilazione, non considerando la variante del tempo di esecuzione ...). Allora saresti forzato per avere funzioni non statiche in tutte le varianti. Ma la chiamata alla funzione virtuale che introduci in questo modo consumerà tutti i vantaggi ottenuti in precedenza dall'uso del modello, quindi potresti anche rimanere con la variante di runtime solo in quel momento e probabilmente starai meglio ...

    
risposta data 19.12.2018 - 20:40
fonte

Leggi altre domande sui tag