Sì, è un parametro non di tipo. Puoi avere diversi tipi di parametri del modello
- Parametri di tipo.
- tipi
- Modelli (solo modelli di classi e alias, nessuna funzione o modelli di variabili)
- Parametri non di tipo
- puntatori
- Riferimenti
- Espressioni costanti integrali
Quello che hai lì è dell'ultimo tipo. È una costante del tempo di compilazione (la cosiddetta espressione costante) ed è di tipo intero o enumerazione. Dopo averlo cercato nello standard, ho dovuto spostare i modelli di classe nella sezione dei tipi, anche se i modelli non sono tipi. Ma sono chiamati parametri di tipo allo scopo di descrivere comunque quei tipi. È possibile avere puntatori (e anche puntatori membri) e riferimenti a oggetti / funzioni che hanno un collegamento esterno (quelli che possono essere collegati da altri file oggetto e il cui indirizzo è univoco nell'intero programma). Esempi:
Parametro del tipo di modello:
template<typename T>
struct Container {
T t;
};
// pass type "long" as argument.
Container<long> test;
Parametro intero modello:
template<unsigned int S>
struct Vector {
unsigned char bytes[S];
};
// pass 3 as argument.
Vector<3> test;
Parametro del puntatore del modello (passaggio di un puntatore a una funzione)
template<void (*F)()>
struct FunctionWrapper {
static void call_it() { F(); }
};
// pass address of function do_it as argument.
void do_it() { }
FunctionWrapper<&do_it> test;
Parametro di riferimento del modello (passaggio di un numero intero)
template<int &A>
struct SillyExample {
static void do_it() { A = 10; }
};
// pass flag as argument
int flag;
SillyExample<flag> test;
Parametro del modello di modello.
template<template<typename T> class AllocatePolicy>
struct Pool {
void allocate(size_t n) {
int *p = AllocatePolicy<int>::allocate(n);
}
};
// pass the template "allocator" as argument.
template<typename T>
struct allocator { static T * allocate(size_t n) { return 0; } };
Pool<allocator> test;
Un modello senza parametri non è possibile. Ma è possibile un modello senza alcun argomento esplicito: ha argomenti predefiniti:
template<unsigned int SIZE = 3>
struct Vector {
unsigned char buffer[SIZE];
};
Vector<> test;
Sintatticamente, template<>
è riservato per contrassegnare una specializzazione di modello esplicita, invece di un modello senza parametri:
template<>
struct Vector<3> {
// alternative definition for SIZE == 3
};
static constexpr int
invece del tuoenum
. Quindi ilFactorial<0>
modello avrebbestatic constexpr int value = 1
etemplate <int N> struct Factorial
può averestatic constexpr int value = N * Factorial<N - 1>::value;