Por que um modelo C ++ que aceita uma matriz não é mais especializado do que aquele que aceita um ponteiro de acordo com o GCC 5.3 e o Clang 4.0?
Por que as próximas duas declarações de modelo são ambíguas (portanto, nenhuma é mais especializada que a outra)? Sei que essa pergunta foi levantada várias vezes no Stack Overflow, mas geralmente as pessoas respondem como resolver a ambiguidade, não por que isso aconteceu.
EU.template <class T> void func(char* buf, T size) {}
IItemplate <std::size_t N> void func(char (&buf)[N], std::size_t size) {}
Tentando executar as etapas do padrão C ++ 14 para resolver a ordem parcial do modelo de função (14.5.6.2):
Para produzir o modelo transformado, para cada tipo, não-tipo ou parâmetro de modelo (incluindo os pacotes de parâmetros do modelo (14.5.3)), sintetize um tipo único, valor ou modelo de classe, respectivamente, e substitua-o por cada ocorrência desse parâmetro no tipo de função do modelo.
Função transformada O tipo de função do modelo é:void func(char*, U1)
, OndeU1
é algum tipo sintético exclusivo.
O tipo de função do modelo da função transformada II é:void func(char (&buf)[N1], std::size_t)
, OndeN1
é algum valor sintético exclusivo.
Usando o tipo de função do modelo de função transformado, execute a dedução de tipo em relação ao outro modelo, conforme descrito em 14.8.2.4.
Então, vamos tentar realizar a dedução de tipo de um lado (usando o primeiro modelo como argumento e o segundo como modelo de parâmetro) e no lado oposto.
Caso 1.Modelo de parâmetro:template <std::size_t N> void func(char (&buf)[N], std::size_t size)
. Modelo de argumento transformado:void func(char*, U1)
.
Tentando deduzir os parâmetros do modelo. "char (&buf)[N]
"não pode ser deduzido de"char*
"type. U1 não correspondestd::size_t
digite também. Falhou.
Modelo de parâmetro:template <class T> void func(char* buf, T size)
. Modelo de argumento transformado:void func(char (&buf)[N1], std::size_t)
.
Tentando deduzir os parâmetros do modelo. O primeiro argumento do modelo de parâmetro não é do tipo e é compatível com umchar[]
. T
deve ser deduzido astd::size_t
.
Portanto, o modelo II deve ser mais especializado e deve ser selecionado no seguinte código:
char buf[16];
func(buf, static_cast<std::size_t>(16));
Por que isso não é verdade para o GCC 5.3 e para o Clang 4.0?