Domanda

È possibile dedurre un parametro del modello non di tipo da un parametro della funzione modello?

Considera questo semplice modello:

template <int N> constexpr int factorial()
{
        return N * factorial<N - 1>();
}

template <> constexpr int factorial<0>()
{
        return 1;
}

template <> constexpr int factorial<1>()
{
        return 1;
}

Vorrei poter cambiare factorial in modo che io possa chiamarlo alternativamente in questo modo:

factorial(5);

e lascia che il compilatore capisca il valore di N al momento della compilazione. È possibile? Forse con qualche fantasiosa aggiunta C ++ 11?

È stato utile?

Soluzione

Non può essere fatto, a meno che tu non abbia una macchina del tempo.

Il parametro alla funzione viene gestito in fase di esecuzione. Sì, in tuo Caso è una costante letterale, ma questo è un caso speciale.

Nelle definizioni delle funzioni, il parametro tipi sono fissati al tempo di compilazione (e quindi, possono essere utilizzati per dedurre i parametri dei modelli), ma parametro i valori sono fissati solo in fase di esecuzione.

Perchè ti serve? È solo così non devi digitare il <>'S?

Altri suggerimenti

Il tuo codice attuale sarebbe normalmente scritto come segue, credo:

constexpr factorial (int n)
{
    return n > 0 ? n * factorial( n - 1 ) : 1;
}

Se lo chiami con un'espressione costante, come factorial(5), quindi tutta la magia del compilatore entrerà in gioco. Ma se lo fai int a = 3; factorial(a), quindi penso che ricadrà su una funzione convenzionale - cioè non avrà costruito una tabella di ricerca di risposte pre -computate.

In generale, dovresti contrassegnare ogni funzione e costruttore come constexpr se potete. Non perdi nulla, il compilatore lo tratterà come una funzione normale, se necessario.

Non credo che tu possa farlo; L'unico modo in cui potresti fare sarebbe avere un constexpr parametro funzione che verrebbe passato allora come il template parametro per la versione modello di factorial, ma constexpr I parametri della funzione non sono ammessi.

No, non è possibile, a meno che tu non voglia creare un'enorme dichiarazione di switch:

int getFactorial( const int v )
{
  switch ( v )
  {
    case 1 : return factorial<1>();
    case 2 : return factorial<2>();
    //etc
    default:
       ;
  }
  return 0;
}

No, non puoi farlo. Gli argomenti del modello possono essere dedotti solo da genere dell'argomento della funzione, non il valore, che in generale non sarà noto al momento della compilazione.

Certo, potresti riscrivere factorial come non-template constexpr funzione; Quindi verrebbe valutato al momento della compilazione se l'argomento è noto allora.

Usa una macro malvagia:

#define factorial(X) factorial<X>()
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top