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.

Caso 2.

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?

questionAnswers(1)

yourAnswerToTheQuestion