Formalmente, cuando se comparan las secuencias de conversión, las transformaciones de lvalue se ignoran. Las conversiones se agrupan en varias categorías, como el ajuste de calificación (T*
->T const*
), transformación lvalue (int[N]
->int*
, void()
->void(*)()
), y otros.
La única diferencia entre sus dos candidatos es una transformación lvalue. Los literales de cadena son matrices que se convierten en punteros. El primer candidato acepta la matriz por referencia y, por lo tanto, no necesitará una transformación lvalue. El segundo candidato requiere una transformación lvalue.
Por lo tanto, si hay dos candidatos que las especializaciones de plantilla de función son igualmente viables al observar solo las conversiones, la regla es que la más especializada se elige haciendo una ordenación parcial de las dos.
Vamos a comparar los dos mirando su firma de su lista de parámetros de función
void(T const&);
void(T*);
Si elegimos algún tipo único Q
por primera lista de parámetros y comprobar si coincide con la segunda lista de parámetros, estamos igualando Q
contra T*
. Esto fallará, ya que Q
no es un puntero. Por lo tanto, el segundo es al menos tan especializado como el primero.
Si hacemos el camino inverso, igualamos Q*
contra T const&
. La referencia se descarta y los calificadores a niveles se ignoran, y el T
restante se convierte en Q*
. Esta es una coincidencia exacta para el fin de la ordenación parcial, y por lo tanto la deducción de la lista de parámetros transformados de la segunda contra el primer candidato tiene éxito. Como la otra dirección (contra la segunda) no tuvo éxito, el segundo candidato es más especializado que el primero, y en consecuencia, la resolución de sobrecarga preferirá la segunda, si hubiera ambigüedad.
En 13.3.3.2/3
:
secuencia de conversión estándar S1 es una secuencia de conversión mejor que la secuencia de conversión estándar S2 si [...]
- S1 es una subsecuencia adecuada de S2 (comparación de las secuencias de conversión en la forma canónica definido por 13.3.3.1.1, con exclusión de cualquier transformación lValue; la secuencia de conversión de identidad se considera que es una subsecuencia de cualquier no secuencia -Identity conversión) o, si no que [...]
Entonces 13.3.3/1
- deje que ICSi (F) denote la secuencia de conversión implícita que convierte el argumento i-th en la lista al tipo del parámetro i-ésimo de la función viable F. 13.3.3.1 define las secuencias de conversión implícitas y 13.3.3.2 define qué significa que una secuencia de conversión implícita es una mejor secuencia de conversión o una secuencia de conversión peor que otra.
Teniendo en cuenta estas definiciones, una función F1 viable se define para ser una función mejor que otro F2 función viable si para todos los argumentos i, ICSI (F1) no es una secuencia de conversión peor que la ICSI (F2), y luego [...]
- F1 y F2 son especializaciones plantilla de función, y la plantilla de función para F1 es más especializado que el molde para la F2 de acuerdo con las reglas de ordenación parciales se describe en 14.5.5.2, o, si no que , [...]
Finalmente, aquí está la tabla de conversiones implícitas que pueden participar en una secuencia de conversión estándar en 13.3.3.1.1/3
.
Conversion sequences http://img259.imageshack.us/img259/851/convs.png
Divertido, MSVC9 nombra la función "foo" en los símbolos de depuración, pero, aparentemente porque reconoce que la implementación es idéntica, usa la misma implementación para ambas llamadas. - Interesante pregunta, de todos modos. –
peterchen
AFAIK VC duplica instancias de plantilla que dan como resultado un código idéntico. – sbi
GCC (4.2.4) hace foo y foo instanciaciones en cualquier cosa hasta -O3, donde simplemente las elides por completo para estas implementaciones y las pone en línea. –