c++ templates compiler-errors const

c++ - Error de deducción de argumento de plantilla al pasar la dirección de tipo const



templates compiler-errors (2)

Como a se declara que se pasa por valor, en la deducción del argumento de la plantilla :

c) de lo contrario, si A es un tipo calificado para cv, los cv-calificadores de nivel superior se ignoran para la deducción:

Eso significa, para go(x, &x); para el primer argumento x , el parámetro de plantilla T se deducirá como int , not const int . Para el segundo argumento, T se deducirá como const int , porque se declara que b se pasa por un puntero (y los cv-calificadores en el objeto que se está apuntando están reservados, lo mismo sucede con la referencia pasada). Entonces la deducción falla.

Por cierto: clang le da un mensaje bastante claro:

prog.cc:4:3: nota: plantilla candidata ignorada: tipos conflictivos deducidos para el parámetro ''T'' (''int'' contra ''const int'')

template <typename T> T go(T a, T *b){ T *t; return *t;} int main() { const int x = 10; go(x, &x); return 0; }

Da error del compilador:

error: no hay función de coincidencia para llamar a ''go (const int &, const int *)''

¿Por qué el primer argumento es un tipo de referencia const int& lugar de simplemente const int ?

Para solucionar este error de compilación, anulé el proceso de deducción del compilador especificando el tipo de argumentos: go<const int>(x, &x); , pero de nuevo ¿por qué tengo que hacer eso?


Es un conflicto de tipo deducción. T se deduce como int del primer argumento, y como const int del segundo argumento. Por lo tanto, la deducción de tipo falla (y el compilador presenta un mensaje que puede o no dejar clara la causa subyacente).

Si desea que esta función funcione sin tener que especificar explícitamente el argumento de la plantilla, puede hacerlo de modo que solo el segundo argumento de la función genere la deducción:

template <class T> struct NonDeduced { using type = T; } template <class T> T go(typename NonDeduced<T>::type a, T *b) { T *t; return *t; }

De esta forma, T solo será deducible del segundo argumento, y el primer parámetro usará la T deducida sin modificación.