Sim, é um parâmetro sem tipo. Você pode ter vários tipos de parâmetros de modelo
- Parâmetros de tipo.
- Tipos
- Modelos (apenas modelos de classes e alias, sem funções ou modelos de variáveis)
- Parâmetros de não tipo
- Ponteiros
- Referências
- Expressões constantes integrais
O que você tem aí é do último tipo. É uma constante de tempo de compilação (chamada de expressão constante) e é do tipo inteiro ou enumeração. Depois de pesquisar no padrão, tive que mover os modelos de classe para a seção de tipos - embora os modelos não sejam tipos. Mas eles são chamados de parâmetros de tipo com o propósito de descrever esses tipos. Você pode ter ponteiros (e também ponteiros de membro) e referências a objetos / funções que têm vínculo externo (aqueles que podem ser vinculados a partir de outros arquivos de objeto e cujo endereço é único em todo o programa). Exemplos:
Parâmetro de tipo de modelo:
template<typename T>
struct Container {
T t;
};
// pass type "long" as argument.
Container<long> test;
Parâmetro de modelo inteiro:
template<unsigned int S>
struct Vector {
unsigned char bytes[S];
};
// pass 3 as argument.
Vector<3> test;
Parâmetro de ponteiro de modelo (passando um ponteiro para uma função)
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;
Parâmetro de referência do modelo (passando um inteiro)
template<int &A>
struct SillyExample {
static void do_it() { A = 10; }
};
// pass flag as argument
int flag;
SillyExample<flag> test;
Parâmetro do modelo de modelo.
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;
Um modelo sem parâmetros não é possível. Mas um modelo sem nenhum argumento explícito é possível - ele tem argumentos padrão:
template<unsigned int SIZE = 3>
struct Vector {
unsigned char buffer[SIZE];
};
Vector<> test;
Sintaticamente, template<>
é reservado para marcar uma especialização de modelo explícita, em vez de um modelo sem parâmetros:
template<>
struct Vector<3> {
// alternative definition for SIZE == 3
};
static constexpr int
vez do seuenum
. Portanto, oFactorial<0>
modelo teriastatic constexpr int value = 1
, etemplate <int N> struct Factorial
pode terstatic constexpr int value = N * Factorial<N - 1>::value;