Reglas de sobrecarga de funciones con plantilla de C ++

Al sobrecargar una función con plantilla, ¿cómo debe elegir el compilador a qué versión de la función llamar si tiene la opción de:

Llame a una versión con plantilla de la función (comofunc<T>(foo))Llame a una versión sobrecargada de la función que no tenga una plantilla en sí, pero que el tipo del parámetro que se pasa a la función herede del tipo especificado en la plantilla de la función sobrecargada.

Considere el siguiente código C ++:

#include <stdio.h>

struct Parent {}; 
struct Child : public Parent {}; 

template <typename T>
void func(T) {
  printf("func(T)\n");
}

void func(Parent) {
  printf("func(Parent)\n");
}

int main() {
  func(1);
  func(Parent());
  func(Child());
}

Compilado con gcc o clang, esto genera:

func(T)
func(Parent)
func(T)

Las primeras dos líneas son esperadas y tienen sentido. Sin embargo, en la convocatoriafunc(Child()), podría llamar fácilmentefunc(Parent) (que parece, en todo caso, lo quedebería hacer).

Como tal, tengo dos preguntas principales:

¿Cuáles son las reglas exactas establecidas por la norma sobre cómo resolver tales conflictos? Hay alguna informacionen esta pregunta / respuesta, pero en todo caso entra en conflicto con lo que estoy observando.¿Hay alguna forma de obligar al compilador a llamarfunc(Parent) cuando pasó unChild?

Puedo superar este requisito en mi propio código y este ejemplo es una versión simplificada de lo que estoy tratando de hacer, pero creo que es el mismo problema.

Respuestas a la pregunta(2)

Su respuesta a la pregunta